Re: [PATCH] Re: [PATCH] Multi protocol support (stage #1)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 6 May 2006, Johannes Stezenbach wrote:
> On Sat, May 06, 2006, Trent Piepho wrote:
> > My thought would be that GET_PARAMS with delivery set to FE_DELSYS_IGNORE
> > would just return frequency.  SET_PARAMS with FE_DELSYS_IGNORE would just set
> > the frequency (and inversion?  Why is inversion here?) and leave the rest of
> > the parameters as is.
> >
> > It's not specified anywhere, but I thought that GET_CAPS with delivery
> > set to FE_DELSYS_IGNORE (wasn't there a QUERY before?) would return
> > the supported delsyses.  Like this:
> >
> > int check_for_atsc(int fd)
> > {
> >     struct dvb_frontend_cap;
> >     cap.delivery = FE_DELSYS_IGNORE; // Get FE type
>
> Thanks, now I get why there once was a FE_DELSYS_QUERY. This
> is totally not obvious from reading frontend.h, it needs to
> be documented with a comment.

Well, that's how *I* thought it would work.  I guess Manu has another idea.
I thought ignore for all the various params was only for GET_PARAMS, to avoid
unnecessary I2C traffic.  GET_CAPS just returns constant values, I can't see
what point IGNORE would have.  I just makes get_params in the driver more
complicated.

There is no real spec or example code yet, so I will write some for
FE_GET_CAPS.  I hope Manu will correct what I get wrong.  IMHO, nothing
I'm writing contradicts anything in Manu's latest multi-protocol support
patch.

Phrases enclosed in brackets [] are optional parts I'm unsure about.

NAME
  FE_GET_CAPS - query front-end capabilities

SYNOPSIS
  int ioctl(int fd, int request = FE_GET_CAPS, struct dvb_frontend_cap *cap);

DESCRIPTION
  This ioctl queries the front-end name, the supported delivery systems,
  delivery system specific parameters such as modulation, and tuning
  parameters such as minimum and maximum frequency.  Real-only access is
  sufficient for this command.

  There are two modes of operation, depending on the value of the
  'delivery' field in the dvb_frontend_cap structure.  The initial value
  of fields other than 'delivery' is ignored.

  When cap.delivery == FE_DELSYS_IGNORE, on return the value of the
  'delivery' field will be a bit set of all the supported delivery
  systems.  The 'name' field MAY [MUST] be set to the device name.  The
  values of remaining fields and undefined and SHOULD be set to zero.
  [If a front-end supports only one delivery system, in which case only a
  single bit will be set in the 'delivery' field, the driver MUST return
  the correct values in the remaining fields.]

  If cap.delivery != FE_DELSYS_IGNORE, it must be set to single delivery
  system from 'enum fe_delsys'.  If multiple bits are set, EINVAL is
  returned in errno.  If the selected delivery system is not supported,
  EINVAL [ENOTSUPP] is returned in errno.  In these cases, the values of
  the remaining fields will be undefined [will be the same as if
  cap.delivery had been set to FE_DELSYS_IGNORE.]

  When cap.delivery is set to a single supported delivery system, the
  correct values will be returned in the remaining fields, as well the
  member of of the 'delsys' union corresponding to the selected delivery
  system.  Each field in the selected member of 'delsys' will be set to a
  bit-mask of all supported values.

  In the case of the field 'modulation' or 'constellation', if the bit
  FE_MOD_AUTO is set, it indicates that the front-end supports
  auto-detection from all other modulations which are supported.  If the
  bit FE_MOD_QAMAUTO is set, it indicates that the front-end supports
  auto-detection from all other QAM modulations that are supported, but not
  between supported QAM modulations and supported non-QAM modulations.

EXAMPLE - USERSPACE

  /* Check if a frontend supports ATSC and print supported modulations */
  int check_atsc(int fd)
  {
      struct dvb_frontend_cap cap;

      // Get supported delivery systems
      cap.delivery = FE_DELSYS_IGNORE;
      ioctl(fd, FE_GET_CAPS, &cap);

      // Fields other than name and delivery may be undefined
      printf("Checking front-end: %s\n", cap.name);

      if(!(cap.delivery & FE_DELSYS_ATSC))  {
          printf("ATSC not supported\n");
          return 0;
      }
      printf("ATSC Supported\n");

      // Check if bits other than ATSC are set, ie. multi-standard
      if(cap.delivery & ~FE_DELSYS_ATSC) {
          printf("Front-end supports additional standards\n");

	  // Need to request just the ATSC parameters
          cap.delivery = FE_DELSYS_ATSC;
          ioctl(fd, FE_GET_CAPS, &cap);
      } /* else only ATSC is supported so we already have ATSC parameters */

      printf("Supported modulations: %s%s%s%s\n",
             cap.delsys.atsc.modulation&FE_MOD_VSB8?"8-VSB ":"",
             cap.delsys.atsc.modulation&FE_MOD_QAM64?"64-QAM ":"",
             cap.delsys.atsc.modulation&FE_MOD_QAM256?"256-QAM ":"",
             cap.delsys.atsc.modulation&FE_MOD_QAMAUTO?"QAM Auto":"");
      return 1;
  }

EXAMPLE - KERNEL

const static struct dvb_frontend_cap or51132_caps = {
	.name = "Oren 51132 VSB/QAM ATSC Demodulator",
	.delivery = FE_DELSYS_ATSC,
	.delsys.atsc = {
		.modulations = FE_MOD_VSB8 | FE_MOD_QAM64 |
		               FE_MOD_QAM256 | FE_MOD_QAMAUTO
	}
}
int or51132_get_caps(struct dvb_frontend *fe, struct dvb_frontend_caps *caps)
{
	if(caps.delivery != FE_DELSYS_ATSC &&
	   caps.delivery != FE_DELSYS_IGNORE)
		return -EINVAL;

	memcpy(caps, &or51132_caps, sizeof(or51132_caps));
	/* Card driver will need to fill in tuner-related parameters
	   after this.  Or we need to chain to a tuner callback here. */

	return 0;
}

EXAMPLE - KERNEL

static const struct dvb_frontend_caps stb0899_dvbs_caps = {
	.name = "STD0899 Multi-standard Front-end",
	.frequency_min = 950000,
	[and so on],
	.delivery = FE_DELSYS_DVBS,
	.delsys.dvbs = {
		.modulation = FE_MOD_QPSK,
		.fecrate = FE_FECRATE_1_2 | FE_FECRATE_2_3 | [...];
	}
};

static const struct dvb_frontend_caps stb0899_dbvs2_caps = {
	.name = "STB0899 Multi-standard Front-end",
	.frequency_min = 950000,
	[and so on],
	.delivery = FE_DELSYS_DVBS2,
	.delsys.dvbs2 = {
		.modulation = FE_MOD_QPSK | FE_MOD_8PSK | FE_MOD_16APSK,
		.fecrate = FE_FECRATE_1_4 | [...] | FE_FECRATE_9_10,
		.streamtype = FE_STREAM_HP | FE_STREAM_LP,
		.coderate_HP = [no idea],
		.coderate_LP = [no idea]
	}
}

int stb0899_get_caps(struct dvb_frontend *fe, struct dvb_frontend_cap *caps)
{
	enum fe_delsys del = caps->delivery;

	switch(del) {
	case FE_DELSYS_DVBS:
	case FE_DELSYS_DSS: /* Same values as DVB-S */
		memcpy(caps, stb0899_dvbs_caps, sizeof(*caps));
		caps.delivery = del;
		return 0;
	case FE_DELSYS_DVBS2:
		memcpy(caps, stb0899_dvbs2_caps, sizeof(*caps));
		return 0;
	case FE_DELSYS_IGNORE:
		strcpy(caps->name, stb0899_dvbs_caps.name);
		caps->delivery = FE_DELSYS_DVBS | FE_DELSYS_DVBS2 |
		                 FE_DELSYS_DSS;
		return 0;
	default:
		return -EINVAL;
	}
}

_______________________________________________

linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux