示例#1
0
/*
 * si4713_powerdown - Powers the device down
 * @sdev: si4713_device structure for the device we are communicating
 */
static int si4713_powerdown(struct si4713_device *sdev)
{
	int err;
	u8 resp[SI4713_PWDN_NRESP];

	if (!sdev->power_state)
		return 0;

	err = si4713_send_command(sdev, SI4713_CMD_POWER_DOWN,
					NULL, 0,
					resp, ARRAY_SIZE(resp),
					DEFAULT_TIMEOUT);

	if (!err) {
		v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n",
				resp[0]);
		v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
		if (gpio_is_valid(sdev->gpio_reset))
			gpio_set_value(sdev->gpio_reset, 0);
		err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies),
					     sdev->supplies);
		if (err)
			v4l2_err(&sdev->sd,
				 "Failed to disable supplies: %d\n", err);
		sdev->power_state = POWER_OFF;
	}

	return err;
}
static int sensor_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
	struct sensor_info *info = to_sensor(sd);
	int ret = 0;
	struct platform_device *pdev;
	int irq = 0;

	v4l2_dbg(1, sensor_debug, sd, "%s", __func__);

	ret = sensor_set_clock(sd, FLITE_ID_C);
	if (ret < 0) {
		sensor_err("sensor set clock fail");
		return ret;
	}

	ret = sensor_init_controls(info);
	if (ret < 0) {
		sensor_err("sensor init contols fail");
		return ret;
	}

	fh->vfh.ctrl_handler = &info->handle;
	sensor_init_formats(sd, fh);

	pdev = get_mipi_csis_pdev(FLITE_ID_C);
	irq = platform_get_irq(pdev, 0);
	v4l2_dbg(1, sensor_debug, sd, "%s : mipi irq num : %d", __func__, irq);

	enable_irq(irq);

	return 0;
}
示例#3
0
static void m5mols_irq_work(struct work_struct *work)
{
	struct m5mols_info *info =
		container_of(work, struct m5mols_info, work_irq);
	struct v4l2_subdev *sd = &info->sd;
	u8 reg;
	int ret;

	if (!is_powered(info) ||
			m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &info->interrupt))
		return;

	switch (info->interrupt & REG_INT_MASK) {
	case REG_INT_AF:
		if (!is_available_af(info))
			break;
		ret = m5mols_read_u8(sd, AF_STATUS, &reg);
		v4l2_dbg(2, m5mols_debug, sd, "AF %s\n",
			 reg == REG_AF_FAIL ? "Failed" :
			 reg == REG_AF_SUCCESS ? "Success" :
			 reg == REG_AF_IDLE ? "Idle" : "Busy");
		break;
	case REG_INT_CAPTURE:
		if (!test_and_set_bit(ST_CAPT_IRQ, &info->flags))
			wake_up_interruptible(&info->irq_waitq);

		v4l2_dbg(2, m5mols_debug, sd, "CAPTURE\n");
		break;
	default:
		v4l2_dbg(2, m5mols_debug, sd, "Undefined: %02x\n", reg);
		break;
	};
}
示例#4
0
static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std)
{
	int err = 0;
	u8 val;
	struct i2c_client *client;

	client = v4l2_get_subdevdata(sd);

	if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
		val = 0x02;
		v4l2_dbg(1, debug, sd, "setting value for SDTV format\n");
	} else {
		val = 0x00;
		v4l2_dbg(1, debug, sd, "disabling all channels\n");
	}

	err |= i2c_smbus_write_byte_data(client, 0x01, val);
	err |= i2c_smbus_write_byte_data(client, 0x02, val);
	err |= i2c_smbus_write_byte_data(client, 0x03, val);

	if (err)
		v4l2_err(sd, "write failed\n");

	return err;
}
示例#5
0
/*
 * si4713_tx_tune_status- Returns the status of the tx_tune_freq, tx_tune_mea or
 * 			tx_tune_power commands. This command return the current
 * 			frequency, output voltage in dBuV, the antenna tunning
 * 			capacitance value and the received noise level. The
 * 			command also clears the stcint interrupt bit when the
 * 			first bit of its arguments is high.
 * @sdev: si4713_device structure for the device we are communicating
 * @intack: 0x01 to clear the seek/tune complete interrupt status indicator.
 * @frequency: returned frequency
 * @power: returned power
 * @antcap: returned antenna capacitance
 * @noise: returned noise level
 */
static int si4713_tx_tune_status(struct si4713_device *sdev, u8 intack,
					u16 *frequency,	u8 *power,
					u8 *antcap, u8 *noise)
{
	int err;
	u8 val[SI4713_TXSTATUS_NRESP];
	/*
	 * 	.First byte = intack bit
	 */
	const u8 args[SI4713_TXSTATUS_NARGS] = {
		intack & SI4713_INTACK_MASK,
	};

	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_STATUS,
				  args, ARRAY_SIZE(args), val,
				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);

	if (!err) {
		v4l2_dbg(1, debug, &sdev->sd,
			"%s: status=0x%02x\n", __func__, val[0]);
		*frequency = compose_u16(val[2], val[3]);
		sdev->frequency = *frequency;
		*power = val[5];
		*antcap = val[6];
		*noise = val[7];
		v4l2_dbg(1, debug, &sdev->sd, "%s: response: %d x 10 kHz "
				"(power %d, antcap %d, rnl %d)\n", __func__,
				*frequency, *power, *antcap, *noise);
	}

	return err;
}
示例#6
0
/*
 * si4713_tx_rds_buff - Loads the RDS group buffer FIFO or circular buffer.
 * @sdev: si4713_device structure for the device we are communicating
 * @mode: the buffer operation mode.
 * @rdsb: RDS Block B
 * @rdsc: RDS Block C
 * @rdsd: RDS Block D
 * @cbleft: returns the number of available circular buffer blocks minus the
 *          number of used circular buffer blocks.
 */
static int si4713_tx_rds_buff(struct si4713_device *sdev, u8 mode, u16 rdsb,
				u16 rdsc, u16 rdsd, s8 *cbleft)
{
	int err;
	u8 val[SI4713_RDSBUFF_NRESP];

	const u8 args[SI4713_RDSBUFF_NARGS] = {
		mode & SI4713_RDSBUFF_MODE_MASK,
		msb(rdsb),
		lsb(rdsb),
		msb(rdsc),
		lsb(rdsc),
		msb(rdsd),
		lsb(rdsd),
	};

	err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_BUFF,
				  args, ARRAY_SIZE(args), val,
				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);

	if (!err) {
		v4l2_dbg(1, debug, &sdev->sd,
			"%s: status=0x%02x\n", __func__, val[0]);
		*cbleft = (s8)val[2] - val[3];
		v4l2_dbg(1, debug, &sdev->sd, "%s: response: interrupts"
				" 0x%02x cb avail: %d cb used %d fifo avail"
				" %d fifo used %d\n", __func__, val[1],
				val[2], val[3], val[4], val[5]);
	}

	return err;
}
/* Receiver */
static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
			      ssize_t *num)
{
	struct cx25840_ir_state *ir_state = to_ir_state(sd);
	bool invert;
	u16 divider;
	unsigned int i, n;
	union cx25840_ir_fifo_rec *p;
	unsigned u, v, w;

	if (ir_state == NULL)
		return -ENODEV;

	invert = (bool) atomic_read(&ir_state->rx_invert);
	divider = (u16) atomic_read(&ir_state->rxclk_divider);

	n = count / sizeof(union cx25840_ir_fifo_rec)
		* sizeof(union cx25840_ir_fifo_rec);
	if (n == 0) {
		*num = 0;
		return 0;
	}

	n = kfifo_out_locked(&ir_state->rx_kfifo, buf, n,
			     &ir_state->rx_kfifo_lock);

	n /= sizeof(union cx25840_ir_fifo_rec);
	*num = n * sizeof(union cx25840_ir_fifo_rec);

	for (p = (union cx25840_ir_fifo_rec *) buf, i = 0; i < n; p++, i++) {

		if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
			/* Assume RTO was because of no IR light input */
			u = 0;
			w = 1;
		} else {
			u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0;
			if (invert)
				u = u ? 0 : 1;
			w = 0;
		}

		v = (unsigned) pulse_width_count_to_ns(
				  (u16) (p->hw_fifo_data & FIFO_RXTX), divider);
		if (v > IR_MAX_DURATION)
			v = IR_MAX_DURATION;

		init_ir_raw_event(&p->ir_core_data);
		p->ir_core_data.pulse = u;
		p->ir_core_data.duration = v;
		p->ir_core_data.timeout = w;

		v4l2_dbg(2, ir_debug, sd, "rx read: %10u ns  %s  %s\n",
			 v, u ? "mark" : "space", w ? "(timed out)" : "");
		if (w)
			v4l2_dbg(2, ir_debug, sd, "rx read: end of rx\n");
	}
	return 0;
}
示例#8
0
/*
 * si4713_powerup - Powers the device up
 * @sdev: si4713_device structure for the device we are communicating
 */
static int si4713_powerup(struct si4713_device *sdev)
{
	int err;
	u8 resp[SI4713_PWUP_NRESP];
	/*
	 * 	.First byte = Enabled interrupts and boot function
	 * 	.Second byte = Input operation mode
	 */
	const u8 args[SI4713_PWUP_NARGS] = {
		SI4713_PWUP_CTSIEN | SI4713_PWUP_GPO2OEN | SI4713_PWUP_FUNC_TX,
		SI4713_PWUP_OPMOD_ANALOG,
	};

	if (sdev->power_state)
		return 0;

	err = regulator_bulk_enable(ARRAY_SIZE(sdev->supplies),
				    sdev->supplies);
	if (err) {
		v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err);
		return err;
	}
	if (gpio_is_valid(sdev->gpio_reset)) {
		udelay(50);
		gpio_set_value(sdev->gpio_reset, 1);
	}

	err = si4713_send_command(sdev, SI4713_CMD_POWER_UP,
					args, ARRAY_SIZE(args),
					resp, ARRAY_SIZE(resp),
					TIMEOUT_POWER_UP);

	if (!err) {
		v4l2_dbg(1, debug, &sdev->sd, "Powerup response: 0x%02x\n",
				resp[0]);
		v4l2_dbg(1, debug, &sdev->sd, "Device in power up mode\n");
		sdev->power_state = POWER_ON;

		err = si4713_write_property(sdev, SI4713_GPO_IEN,
						SI4713_STC_INT | SI4713_CTS);
	} else {
		if (gpio_is_valid(sdev->gpio_reset))
			gpio_set_value(sdev->gpio_reset, 0);
		err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies),
					     sdev->supplies);
		if (err)
			v4l2_err(&sdev->sd,
				 "Failed to disable supplies: %d\n", err);
	}

	return err;
}
示例#9
0
/* Receiver */
static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
			      ssize_t *num)
{
	struct cx23888_ir_state *state = to_state(sd);
	bool invert = (bool) atomic_read(&state->rx_invert);
	u16 divider = (u16) atomic_read(&state->rxclk_divider);

	unsigned int i, n;
	u32 *p;
	u32 u, v;

	n = count / sizeof(u32) * sizeof(u32);
	if (n == 0) {
		*num = 0;
		return 0;
	}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
	n = kfifo_get(state->rx_kfifo, buf, n);
#else
	n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock);
#endif

	n /= sizeof(u32);
	*num = n * sizeof(u32);

	for (p = (u32 *) buf, i = 0; i < n; p++, i++) {
		if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
			*p = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
			v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n");
			continue;
		}

		u = (*p & FIFO_RXTX_LVL) ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0;
		if (invert)
			u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK;

		v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX),
						  divider);
		if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
			v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1;

		*p = u | v;

		v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns  %s\n",
			 v, u ? "mark" : "space");
	}
	return 0;
}
示例#10
0
static int mt9v011_s_config(struct v4l2_subdev *sd, int dumb, void *data)
{
	struct mt9v011 *core = to_mt9v011(sd);
	unsigned *xtal = data;

	v4l2_dbg(1, debug, sd, "s_config called\n");

	if (xtal) {
		core->xtal = *xtal;
		v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n",
			 *xtal / 1000000, (*xtal / 1000) % 1000);
	}

	return 0;
}
示例#11
0
/*
 * si4713_tx_tune_power - Sets the RF voltage level between 88 and 115 dBuV in
 * 			1 dB units. A value of 0x00 indicates off. The command
 * 			also sets the antenna tuning capacitance. A value of 0
 * 			indicates autotuning, and a value of 1 - 191 indicates
 * 			a manual override, which results in a tuning
 * 			capacitance of 0.25 pF x @antcap.
 * @sdev: si4713_device structure for the device we are communicating
 * @power: tuning power (88 - 115 dBuV, unit/step 1 dB)
 * @antcap: value of antenna tuning capacitor (0 - 191)
 */
static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
				u8 antcap)
{
	int err;
	u8 val[SI4713_TXPWR_NRESP];
	/*
	 * 	.First byte = 0
	 * 	.Second byte = 0
	 * 	.Third byte = power
	 * 	.Fourth byte = antcap
	 */
	const u8 args[SI4713_TXPWR_NARGS] = {
		0x00,
		0x00,
		power,
		antcap,
	};

	if (((power > 0) && (power < SI4713_MIN_POWER)) ||
		power > SI4713_MAX_POWER || antcap > SI4713_MAX_ANTCAP)
		return -EDOM;

	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_POWER,
				  args, ARRAY_SIZE(args), val,
				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);

	if (err < 0)
		return err;

	v4l2_dbg(1, debug, &sdev->sd,
			"%s: power=0x%02x antcap=0x%02x status=0x%02x\n",
			__func__, power, antcap, val[0]);

	return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE_POWER);
}
示例#12
0
文件: tda9840.c 项目: 020gzh/linux
static int tda9840_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *t)
{
	int stat = tda9840_status(sd);
	int byte;

	if (t->index)
		return -EINVAL;

	stat = stat < 0 ? 0 : stat;
	if (stat == 0 || stat == 0x60) /* mono input */
		byte = TDA9840_SET_MONO;
	else if (stat == 0x40) /* stereo input */
		byte = (t->audmode == V4L2_TUNER_MODE_MONO) ?
			TDA9840_SET_MONO : TDA9840_SET_STEREO;
	else { /* bilingual */
		switch (t->audmode) {
		case V4L2_TUNER_MODE_LANG1_LANG2:
			byte = TDA9840_SET_BOTH;
			break;
		case V4L2_TUNER_MODE_LANG2:
			byte = TDA9840_SET_LANG2;
			break;
		default:
			byte = TDA9840_SET_LANG1;
			break;
		}
	}
	v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
	tda9840_write(sd, SWITCH, byte);
	return 0;
}
示例#13
0
/**
 * m5mols_fw_start - M-5MOLS internal ARM controller initialization
 *
 * Execute the M-5MOLS internal ARM controller initialization sequence.
 * This function should be called after the supply voltage has been
 * applied and before any requests to the device are made.
 */
static int m5mols_fw_start(struct v4l2_subdev *sd)
{
	struct m5mols_info *info = to_m5mols(sd);
	int ret;

	atomic_set(&info->irq_done, 0);
	/* Wait until I2C slave is initialized in Flash Writer mode */
	ret = m5mols_busy_wait(sd, FLASH_CAM_START, REG_IN_FLASH_MODE,
			       M5MOLS_I2C_RDY_WAIT_FL | 0xff, -1);
	if (!ret)
		ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
	if (!ret)
		ret = m5mols_wait_interrupt(sd, REG_INT_MODE, 2000);
	if (ret < 0)
		return ret;

	info->isp_ready = 1;

	ret = m5mols_get_version(sd);
	if (!ret)
		ret = m5mols_update_fw(sd, m5mols_sensor_power);
	if (ret)
		return ret;

	v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n");

	ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI);
	if (!ret)
		ret = m5mols_enable_interrupt(sd,
				REG_INT_AF | REG_INT_CAPTURE);

	return ret;
}
示例#14
0
/*
 * si4713_read_property - reads a si4713 property
 * @sdev: si4713_device structure for the device we are communicating
 * @prop: property identification number
 * @pv: property value to be returned on success
 */
static int si4713_read_property(struct si4713_device *sdev, u16 prop, u32 *pv)
{
	int err;
	u8 val[SI4713_GET_PROP_NRESP];
	/*
	 * 	.First byte = 0
	 * 	.Second byte = property's MSB
	 * 	.Third byte = property's LSB
	 */
	const u8 args[SI4713_GET_PROP_NARGS] = {
		0x00,
		msb(prop),
		lsb(prop),
	};

	err = si4713_send_command(sdev, SI4713_CMD_GET_PROPERTY,
				  args, ARRAY_SIZE(args), val,
				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);

	if (err < 0)
		return err;

	*pv = compose_u16(val[2], val[3]);

	v4l2_dbg(1, debug, &sdev->sd,
			"%s: property=0x%02x value=0x%02x status=0x%02x\n",
			__func__, prop, *pv, val[0]);

	return err;
}
示例#15
0
/*
 * si4713_tx_tune_power - Sets the RF voltage level between 88 and 120 dBuV in
 *			1 dB units. A value of 0x00 indicates off. The command
 *			also sets the antenna tuning capacitance. A value of 0
 *			indicates autotuning, and a value of 1 - 191 indicates
 *			a manual override, which results in a tuning
 *			capacitance of 0.25 pF x @antcap.
 * @sdev: si4713_device structure for the device we are communicating
 * @power: tuning power (88 - 120 dBuV, unit/step 1 dB)
 * @antcap: value of antenna tuning capacitor (0 - 191)
 */
static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
				u8 antcap)
{
	int err;
	u8 val[SI4713_TXPWR_NRESP];
	/*
	 *	.First byte = 0
	 *	.Second byte = 0
	 *	.Third byte = power
	 *	.Fourth byte = antcap
	 */
	u8 args[SI4713_TXPWR_NARGS] = {
		0x00,
		0x00,
		power,
		antcap,
	};

	/* Map power values 1-87 to MIN_POWER (88) */
	if (power > 0 && power < SI4713_MIN_POWER)
		args[2] = power = SI4713_MIN_POWER;

	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_POWER,
				  args, ARRAY_SIZE(args), val,
				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);

	if (err < 0)
		return err;

	v4l2_dbg(1, debug, &sdev->sd,
			"%s: power=0x%02x antcap=0x%02x status=0x%02x\n",
			__func__, power, antcap, val[0]);

	return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE_POWER);
}
static int vpbe_buffer_prepare(struct videobuf_queue *q,
				  struct videobuf_buffer *vb,
				  enum v4l2_field field)
{
	struct vpbe_fh *fh = q->priv_data;
	struct vpbe_layer *layer = fh->layer;
	struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
	unsigned long addr;
	int ret;

	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
				"vpbe_buffer_prepare\n");

	
	if (VIDEOBUF_NEEDS_INIT == vb->state) {
		vb->width = layer->pix_fmt.width;
		vb->height = layer->pix_fmt.height;
		vb->size = layer->pix_fmt.sizeimage;
		vb->field = field;

		ret = videobuf_iolock(q, vb, NULL);
		if (ret < 0) {
			v4l2_err(&vpbe_dev->v4l2_dev, "Failed to map \
				user address\n");
			return -EINVAL;
		}
示例#17
0
static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
{
	int byte;

	if (t->index)
		return -EINVAL;

	switch (t->audmode) {
	case V4L2_TUNER_MODE_STEREO:
		byte = TDA9840_SET_STEREO;
		break;
	case V4L2_TUNER_MODE_LANG1_LANG2:
		byte = TDA9840_SET_BOTH;
		break;
	case V4L2_TUNER_MODE_LANG1:
		byte = TDA9840_SET_LANG1;
		break;
	case V4L2_TUNER_MODE_LANG2:
		byte = TDA9840_SET_LANG2;
		break;
	default:
		byte = TDA9840_SET_MONO;
		break;
	}
	v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
	tda9840_write(sd, SWITCH, byte);
	return 0;
}
示例#18
0
static int tda9840_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	struct v4l2_subdev *sd;
	int result;
	int byte;

	/* let's see whether this adapter can support what we need */
	if (!i2c_check_functionality(client->adapter,
			I2C_FUNC_SMBUS_READ_BYTE_DATA |
			I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
		return -EIO;

	v4l_info(client, "chip found @ 0x%x (%s)\n",
			client->addr << 1, client->adapter->name);

	sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
	if (sd == NULL)
		return -ENOMEM;
	v4l2_i2c_subdev_init(sd, client, &tda9840_ops);

	/* set initial values for level & stereo - adjustment, mode */
	byte = 0;
	result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte);
	result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte);
	tda9840_write(sd, SWITCH, TDA9840_SET_STEREO);
	if (result) {
		v4l2_dbg(1, debug, sd, "could not initialize tda9840\n");
		kfree(sd);
		return -ENODEV;
	}
	return 0;
}
int get_input_lines_info(struct hdpvr_device *dev)
{
#ifdef HDPVR_DEBUG
	char print_buf[9];
#endif
	int ret, lines;

	mutex_lock(&dev->usbc_mutex);
	ret = usb_control_msg(dev->udev,
			      usb_rcvctrlpipe(dev->udev, 0),
			      0x81, 0x80 | 0x38,
			      0x1800, 0x0003,
			      dev->usbc_buf, 3,
			      1000);

#ifdef HDPVR_DEBUG
	if (hdpvr_debug & MSG_INFO) {
		hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf,
				   sizeof(print_buf), 0);
		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
			 "get input lines info returned: %d, %s\n", ret,
			 print_buf);
	}
#endif
	lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
	mutex_unlock(&dev->usbc_mutex);
	return lines;
}
示例#20
0
/*
 * si4713_wait_stc - Waits STC interrupt and clears status bits. Useful
 *		     for TX_TUNE_POWER, TX_TUNE_FREQ and TX_TUNE_MEAS
 * @sdev: si4713_device structure for the device we are communicating
 * @usecs: timeout to wait for STC interrupt signal
 */
static int si4713_wait_stc(struct si4713_device *sdev, const int usecs)
{
	int err;
	u8 resp[SI4713_GET_STATUS_NRESP];

	/* Wait response from STC interrupt */
	if (!wait_for_completion_timeout(&sdev->work,
			usecs_to_jiffies(usecs) + 1))
		v4l2_warn(&sdev->sd,
			"%s: device took too much time to answer (%d usec).\n",
				__func__, usecs);

	/* Clear status bits */
	err = si4713_send_command(sdev, SI4713_CMD_GET_INT_STATUS,
					NULL, 0,
					resp, ARRAY_SIZE(resp),
					DEFAULT_TIMEOUT);

	if (err < 0)
		goto exit;

	v4l2_dbg(1, debug, &sdev->sd,
			"%s: status bits: 0x%02x\n", __func__, resp[0]);

	if (!(resp[0] & SI4713_STC_INT))
		err = -EIO;

exit:
	return err;
}
示例#21
0
/*
 * si4713_tx_tune_freq - Sets the state of the RF carrier and sets the tuning
 * 			frequency between 76 and 108 MHz in 10 kHz units and
 * 			steps of 50 kHz.
 * @sdev: si4713_device structure for the device we are communicating
 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
 */
static int si4713_tx_tune_freq(struct si4713_device *sdev, u16 frequency)
{
	int err;
	u8 val[SI4713_TXFREQ_NRESP];
	/*
	 * 	.First byte = 0
	 * 	.Second byte = frequency's MSB
	 * 	.Third byte = frequency's LSB
	 */
	const u8 args[SI4713_TXFREQ_NARGS] = {
		0x00,
		msb(frequency),
		lsb(frequency),
	};

	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_FREQ,
				  args, ARRAY_SIZE(args), val,
				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);

	if (err < 0)
		return err;

	v4l2_dbg(1, debug, &sdev->sd,
			"%s: frequency=0x%02x status=0x%02x\n", __func__,
			frequency, val[0]);

	err = si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
	if (err < 0)
		return err;

	return compose_u16(args[1], args[2]);
}
示例#22
0
/*
 * si4713_tx_rds_ps - Loads the program service buffer.
 * @sdev: si4713_device structure for the device we are communicating
 * @psid: program service id to be loaded.
 * @pschar: assumed 4 size char array to be loaded into the program service
 */
static int si4713_tx_rds_ps(struct si4713_device *sdev, u8 psid,
				unsigned char *pschar)
{
	int err;
	u8 val[SI4713_RDSPS_NRESP];

	const u8 args[SI4713_RDSPS_NARGS] = {
		psid & SI4713_RDSPS_PSID_MASK,
		pschar[0],
		pschar[1],
		pschar[2],
		pschar[3],
	};

	err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_PS,
				  args, ARRAY_SIZE(args), val,
				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);

	if (err < 0)
		return err;

	v4l2_dbg(1, debug, &sdev->sd, "%s: status=0x%02x\n", __func__, val[0]);

	return err;
}
示例#23
0
static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
	struct mt9v011 *core = to_mt9v011(sd);

	v4l2_dbg(1, debug, sd, "g_ctrl called\n");

	switch (ctrl->id) {
	case V4L2_CID_GAIN:
		ctrl->value = core->global_gain;
		return 0;
	case V4L2_CID_EXPOSURE:
		ctrl->value = core->exposure;
		return 0;
	case V4L2_CID_RED_BALANCE:
		ctrl->value = core->red_bal;
		return 0;
	case V4L2_CID_BLUE_BALANCE:
		ctrl->value = core->blue_bal;
		return 0;
	case V4L2_CID_HFLIP:
		ctrl->value = core->hflip ? 1 : 0;
		return 0;
	case V4L2_CID_VFLIP:
		ctrl->value = core->vflip ? 1 : 0;
		return 0;
	}
	return -EINVAL;
}
示例#24
0
static void calc_fps(struct v4l2_subdev *sd, u32 *numerator, u32 *denominator)
{
	struct mt9v011 *core = to_mt9v011(sd);
	unsigned height, width, hblank, vblank, speed;
	unsigned row_time, t_time;
	u64 frames_per_ms;
	unsigned tmp;

	height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
	width = mt9v011_read(sd, R04_MT9V011_WIDTH);
	hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
	vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
	speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED);

	row_time = (width + 113 + hblank) * (speed + 2);
	t_time = row_time * (height + vblank + 1);

	frames_per_ms = core->xtal * 1000l;
	do_div(frames_per_ms, t_time);
	tmp = frames_per_ms;

	v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n",
		tmp / 1000, tmp % 1000, t_time);

	if (numerator && denominator) {
		*numerator = 1000;
		*denominator = (u32)frames_per_ms;
	}
}
示例#25
0
int get_video_info(struct hdpvr_device *dev, struct hdpvr_video_info *vidinf)
{
	int ret;

	vidinf->valid = false;
	mutex_lock(&dev->usbc_mutex);
	ret = usb_control_msg(dev->udev,
			      usb_rcvctrlpipe(dev->udev, 0),
			      0x81, 0x80 | 0x38,
			      0x1400, 0x0003,
			      dev->usbc_buf, 5,
			      1000);

#ifdef HDPVR_DEBUG
	if (hdpvr_debug & MSG_INFO)
		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
			 "get video info returned: %d, %5ph\n", ret,
			 dev->usbc_buf);
#endif
	mutex_unlock(&dev->usbc_mutex);

	if (ret < 0)
		return ret;

	vidinf->width	= dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
	vidinf->height	= dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
	vidinf->fps	= dev->usbc_buf[4];
	vidinf->valid   = vidinf->width && vidinf->height && vidinf->fps;

	return 0;
}
示例#26
0
static void __configure_output(struct atomisp_sub_device *isp_subdev,
			       unsigned int width,
			       unsigned int height,
			       enum ia_css_frame_format format,
			       enum ia_css_pipe_id pipe_id)
{
	isp_subdev->css2_basis.curr_pipe = pipe_id;
	isp_subdev->css2_basis.pipe_configs[pipe_id].mode =
	    __pipe_id_to_pipe_mode(pipe_id);
	isp_subdev->css2_basis.update_pipe[pipe_id] = true;

	isp_subdev->css2_basis.pipe_configs[pipe_id].
			output_info.res.width = width;
	isp_subdev->css2_basis.pipe_configs[pipe_id].
			output_info.res.height = height;
	isp_subdev->css2_basis.pipe_configs[pipe_id].
			output_info.format = format;

	if (width * height >
	    isp_subdev->css2_basis.stream_config.
	    effective_res.width *
	    isp_subdev->css2_basis.stream_config.
	    effective_res.height) {
		isp_subdev->css2_basis.stream_config.
		    effective_res.width = width;
		isp_subdev->css2_basis.stream_config.
		    effective_res.height = height;
	}

	v4l2_dbg(3, dbg_level, &atomisp_dev,
		 "configuring pipe[%d] output info w=%d.h=%d.f=%d.\n",
		 pipe_id, width, height, format);
}
示例#27
0
static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
					u32 *width, u32 *height,
					u32 *code, u32 *fourcc, int pad)
{
	struct flite_variant *variant = fimc->variant;
	const struct fimc_fmt *fmt;

	fmt = fimc_lite_find_format(fourcc, code, 0);
	if (WARN_ON(!fmt))
		return NULL;

	if (code)
		*code = fmt->mbus_code;
	if (fourcc)
		*fourcc = fmt->fourcc;

	if (pad == FLITE_SD_PAD_SINK) {
		v4l_bound_align_image(width, 8, variant->max_width,
				      ffs(variant->out_width_align) - 1,
				      height, 0, variant->max_height, 0, 0);
	} else {
		v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
				      ffs(variant->out_width_align) - 1,
				      height, 0, fimc->inp_frame.rect.height,
				      0, 0);
	}

	v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
		 code ? *code : 0, *width, *height);

	return fmt;
}
示例#28
0
static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
					  struct v4l2_subdev_fh *fh,
					  struct v4l2_subdev_selection *sel)
{
	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
	struct flite_frame *f = &fimc->inp_frame;
	int ret = 0;

	if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != FLITE_SD_PAD_SINK)
		return -EINVAL;

	mutex_lock(&fimc->lock);
	fimc_lite_try_crop(fimc, &sel->r);

	if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
		*v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r;
	} else {
		unsigned long flags;
		spin_lock_irqsave(&fimc->slock, flags);
		f->rect = sel->r;
		/* Same crop rectangle on the source pad */
		fimc->out_frame.rect = sel->r;
		set_bit(ST_FLITE_CONFIG, &fimc->state);
		spin_unlock_irqrestore(&fimc->slock, flags);
	}
	mutex_unlock(&fimc->lock);

	v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
		 __func__, f->rect.left, f->rect.top, f->rect.width,
		 f->rect.height, f->f_width, f->f_height);

	return ret;
}
示例#29
0
static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
					  struct v4l2_subdev_fh *fh,
					  struct v4l2_subdev_selection *sel)
{
	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
	struct flite_frame *f = &fimc->inp_frame;

	if ((sel->target != V4L2_SEL_TGT_CROP &&
	     sel->target != V4L2_SEL_TGT_CROP_BOUNDS) ||
	     sel->pad != FLITE_SD_PAD_SINK)
		return -EINVAL;

	if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
		sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
		return 0;
	}

	mutex_lock(&fimc->lock);
	if (sel->target == V4L2_SEL_TGT_CROP) {
		sel->r = f->rect;
	} else {
		sel->r.left = 0;
		sel->r.top = 0;
		sel->r.width = f->f_width;
		sel->r.height = f->f_height;
	}
	mutex_unlock(&fimc->lock);

	v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
		 __func__, f->rect.left, f->rect.top, f->rect.width,
		 f->rect.height, f->f_width, f->f_height);

	return 0;
}
示例#30
0
文件: fimc-lite.c 项目: 19Dan01/linux
/* Capture subdev media entity operations */
static int fimc_lite_link_setup(struct media_entity *entity,
				const struct media_pad *local,
				const struct media_pad *remote, u32 flags)
{
	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
	unsigned int remote_ent_type = media_entity_type(remote->entity);
	int ret = 0;

	if (WARN_ON(fimc == NULL))
		return 0;

	v4l2_dbg(1, debug, sd, "%s: %s --> %s, flags: 0x%x. source_id: 0x%x\n",
		 __func__, remote->entity->name, local->entity->name,
		 flags, fimc->source_subdev_grp_id);

	switch (local->index) {
	case FLITE_SD_PAD_SINK:
		if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
			ret = -EINVAL;
			break;
		}
		if (flags & MEDIA_LNK_FL_ENABLED) {
			if (fimc->source_subdev_grp_id == 0)
				fimc->source_subdev_grp_id = sd->grp_id;
			else
				ret = -EBUSY;
		} else {
			fimc->source_subdev_grp_id = 0;
			fimc->sensor = NULL;
		}
		break;

	case FLITE_SD_PAD_SOURCE_DMA:
		if (!(flags & MEDIA_LNK_FL_ENABLED))
			atomic_set(&fimc->out_path, FIMC_IO_NONE);
		else if (remote_ent_type == MEDIA_ENT_T_DEVNODE)
			atomic_set(&fimc->out_path, FIMC_IO_DMA);
		else
			ret = -EINVAL;
		break;

	case FLITE_SD_PAD_SOURCE_ISP:
		if (!(flags & MEDIA_LNK_FL_ENABLED))
			atomic_set(&fimc->out_path, FIMC_IO_NONE);
		else if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
			atomic_set(&fimc->out_path, FIMC_IO_ISP);
		else
			ret = -EINVAL;
		break;

	default:
		v4l2_err(sd, "Invalid pad index\n");
		ret = -EINVAL;
	}
	mb();

	return ret;
}