static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd, struct v4l2_subdev_ir_parameters *p) { struct cx23888_ir_state *state = to_state(sd); struct cx23885_dev *dev = state->dev; struct v4l2_subdev_ir_parameters *o = &state->tx_params; u16 txclk_divider; if (p->shutdown) return cx23888_ir_tx_shutdown(sd); if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH) return -ENOSYS; mutex_lock(&state->tx_params_lock); o->shutdown = p->shutdown; o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; o->bytes_per_data_element = p->bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec); /* Before we tweak the hardware, we have to disable the transmitter */ irqenable_tx(dev, 0); control_tx_enable(dev, false); control_tx_modulation_enable(dev, p->modulation); o->modulation = p->modulation; if (p->modulation) { p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq, &txclk_divider); o->carrier_freq = p->carrier_freq; p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle); o->duty_cycle = p->duty_cycle; p->max_pulse_width = (u32) pulse_width_count_to_ns(FIFO_RXTX, txclk_divider); } else { p->max_pulse_width = txclk_tx_s_max_pulse_width(dev, p->max_pulse_width, &txclk_divider); } o->max_pulse_width = p->max_pulse_width; atomic_set(&state->txclk_divider, txclk_divider); p->resolution = clock_divider_to_resolution(txclk_divider); o->resolution = p->resolution; /* FIXME - make this dependent on resolution for better performance */ control_tx_irq_watermark(dev, TX_FIFO_HALF_EMPTY); control_tx_polarity_invert(dev, p->invert_carrier_sense); o->invert_carrier_sense = p->invert_carrier_sense; control_tx_level_invert(dev, p->invert_level); o->invert_level = p->invert_level; o->interrupt_enable = p->interrupt_enable; o->enable = p->enable; if (p->enable) { if (p->interrupt_enable) irqenable_tx(dev, IRQEN_TSE); control_tx_enable(dev, p->enable); } mutex_unlock(&state->tx_params_lock); return 0; }
static int cx25840_ir_tx_s_parameters(struct v4l2_subdev *sd, struct v4l2_subdev_ir_parameters *p) { struct cx25840_ir_state *ir_state = to_ir_state(sd); struct i2c_client *c; struct v4l2_subdev_ir_parameters *o; u16 txclk_divider; if (ir_state == NULL) return -ENODEV; if (p->shutdown) return cx25840_ir_tx_shutdown(sd); if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH) return -ENOSYS; c = ir_state->c; o = &ir_state->tx_params; mutex_lock(&ir_state->tx_params_lock); o->shutdown = p->shutdown; p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; o->mode = p->mode; p->bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec); o->bytes_per_data_element = p->bytes_per_data_element; /* Before we tweak the hardware, we have to disable the transmitter */ irqenable_tx(sd, 0); control_tx_enable(c, false); control_tx_modulation_enable(c, p->modulation); o->modulation = p->modulation; if (p->modulation) { p->carrier_freq = txclk_tx_s_carrier(c, p->carrier_freq, &txclk_divider); o->carrier_freq = p->carrier_freq; p->duty_cycle = cduty_tx_s_duty_cycle(c, p->duty_cycle); o->duty_cycle = p->duty_cycle; p->max_pulse_width = (u32) pulse_width_count_to_ns(FIFO_RXTX, txclk_divider); } else { p->max_pulse_width = txclk_tx_s_max_pulse_width(c, p->max_pulse_width, &txclk_divider); } o->max_pulse_width = p->max_pulse_width; atomic_set(&ir_state->txclk_divider, txclk_divider); p->resolution = clock_divider_to_resolution(txclk_divider); o->resolution = p->resolution; /* FIXME - make this dependent on resolution for better performance */ control_tx_irq_watermark(c, TX_FIFO_HALF_EMPTY); control_tx_polarity_invert(c, p->invert_carrier_sense); o->invert_carrier_sense = p->invert_carrier_sense; /* * FIXME: we don't have hardware help for IO pin level inversion * here like we have on the CX23888. * Act on this with some mix of logical inversion of data levels, * carrier polarity, and carrier duty cycle. */ o->invert_level = p->invert_level; o->interrupt_enable = p->interrupt_enable; o->enable = p->enable; if (p->enable) { /* reset tx_fifo here */ if (p->interrupt_enable) irqenable_tx(sd, IRQEN_TSE); control_tx_enable(c, p->enable); } mutex_unlock(&ir_state->tx_params_lock); return 0; }