Lines Matching +full:no +full:- +full:sd

1 // SPDX-License-Identifier: GPL-2.0-or-later
11 #include "cx23888-ir.h"
16 #include <media/v4l2-device.h>
17 #include <media/rc-core.h>
117 struct v4l2_subdev sd; member
133 static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) in to_state() argument
135 return v4l2_get_subdevdata(sd); in to_state()
174 d--; in count_to_clock_divider()
306 count--; in pulse_clocks_to_clock_divider()
384 if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) { in control_rx_s_carrier_window()
386 *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4); in control_rx_s_carrier_window()
389 *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3); in control_rx_s_carrier_window()
464 n--; in cduty_tx_s_duty_cycle()
500 static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, in cx23888_ir_irq_handler() argument
503 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_irq_handler()
504 struct cx23885_dev *dev = state->dev; in cx23888_ir_irq_handler()
527 v4l2_dbg(2, ir_888_debug, sd, "IRQ Status: %s %s %s %s %s %s\n", in cx23888_ir_irq_handler()
533 v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n", in cx23888_ir_irq_handler()
554 v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events); in cx23888_ir_irq_handler()
579 k = kfifo_in_locked(&state->rx_kfifo, in cx23888_ir_irq_handler()
581 &state->rx_kfifo_lock); in cx23888_ir_irq_handler()
592 v4l2_err(sd, "IR receiver software FIFO overrun\n"); in cx23888_ir_irq_handler()
601 v4l2_err(sd, "IR receiver hardware FIFO overrun\n"); in cx23888_ir_irq_handler()
618 spin_lock_irqsave(&state->rx_kfifo_lock, flags); in cx23888_ir_irq_handler()
619 if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) in cx23888_ir_irq_handler()
621 spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); in cx23888_ir_irq_handler()
624 v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); in cx23888_ir_irq_handler()
629 static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, in cx23888_ir_rx_read() argument
632 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_rx_read()
633 bool invert = (bool) atomic_read(&state->rx_invert); in cx23888_ir_rx_read()
634 u16 divider = (u16) atomic_read(&state->rxclk_divider); in cx23888_ir_rx_read()
647 n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock); in cx23888_ir_rx_read()
654 if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) { in cx23888_ir_rx_read()
655 /* Assume RTO was because of no IR light input */ in cx23888_ir_rx_read()
659 u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0; in cx23888_ir_rx_read()
666 (u16)(p->hw_fifo_data & FIFO_RXTX), divider) / 1000; in cx23888_ir_rx_read()
670 p->ir_core_data = (struct ir_raw_event) in cx23888_ir_rx_read()
673 v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s %s\n", in cx23888_ir_rx_read()
676 v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n"); in cx23888_ir_rx_read()
681 static int cx23888_ir_rx_g_parameters(struct v4l2_subdev *sd, in cx23888_ir_rx_g_parameters() argument
684 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_rx_g_parameters()
685 mutex_lock(&state->rx_params_lock); in cx23888_ir_rx_g_parameters()
686 memcpy(p, &state->rx_params, sizeof(struct v4l2_subdev_ir_parameters)); in cx23888_ir_rx_g_parameters()
687 mutex_unlock(&state->rx_params_lock); in cx23888_ir_rx_g_parameters()
691 static int cx23888_ir_rx_shutdown(struct v4l2_subdev *sd) in cx23888_ir_rx_shutdown() argument
693 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_rx_shutdown()
694 struct cx23885_dev *dev = state->dev; in cx23888_ir_rx_shutdown()
696 mutex_lock(&state->rx_params_lock); in cx23888_ir_rx_shutdown()
706 state->rx_params.shutdown = true; in cx23888_ir_rx_shutdown()
708 mutex_unlock(&state->rx_params_lock); in cx23888_ir_rx_shutdown()
712 static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd, in cx23888_ir_rx_s_parameters() argument
715 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_rx_s_parameters()
716 struct cx23885_dev *dev = state->dev; in cx23888_ir_rx_s_parameters()
717 struct v4l2_subdev_ir_parameters *o = &state->rx_params; in cx23888_ir_rx_s_parameters()
720 if (p->shutdown) in cx23888_ir_rx_s_parameters()
721 return cx23888_ir_rx_shutdown(sd); in cx23888_ir_rx_s_parameters()
723 if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH) in cx23888_ir_rx_s_parameters()
724 return -ENOSYS; in cx23888_ir_rx_s_parameters()
726 mutex_lock(&state->rx_params_lock); in cx23888_ir_rx_s_parameters()
728 o->shutdown = p->shutdown; in cx23888_ir_rx_s_parameters()
730 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; in cx23888_ir_rx_s_parameters()
732 o->bytes_per_data_element = p->bytes_per_data_element in cx23888_ir_rx_s_parameters()
739 control_rx_demodulation_enable(dev, p->modulation); in cx23888_ir_rx_s_parameters()
740 o->modulation = p->modulation; in cx23888_ir_rx_s_parameters()
742 if (p->modulation) { in cx23888_ir_rx_s_parameters()
743 p->carrier_freq = rxclk_rx_s_carrier(dev, p->carrier_freq, in cx23888_ir_rx_s_parameters()
746 o->carrier_freq = p->carrier_freq; in cx23888_ir_rx_s_parameters()
748 o->duty_cycle = p->duty_cycle = 50; in cx23888_ir_rx_s_parameters()
750 control_rx_s_carrier_window(dev, p->carrier_freq, in cx23888_ir_rx_s_parameters()
751 &p->carrier_range_lower, in cx23888_ir_rx_s_parameters()
752 &p->carrier_range_upper); in cx23888_ir_rx_s_parameters()
753 o->carrier_range_lower = p->carrier_range_lower; in cx23888_ir_rx_s_parameters()
754 o->carrier_range_upper = p->carrier_range_upper; in cx23888_ir_rx_s_parameters()
756 p->max_pulse_width = in cx23888_ir_rx_s_parameters()
759 p->max_pulse_width = in cx23888_ir_rx_s_parameters()
760 rxclk_rx_s_max_pulse_width(dev, p->max_pulse_width, in cx23888_ir_rx_s_parameters()
763 o->max_pulse_width = p->max_pulse_width; in cx23888_ir_rx_s_parameters()
764 atomic_set(&state->rxclk_divider, rxclk_divider); in cx23888_ir_rx_s_parameters()
766 p->noise_filter_min_width = in cx23888_ir_rx_s_parameters()
767 filter_rx_s_min_width(dev, p->noise_filter_min_width); in cx23888_ir_rx_s_parameters()
768 o->noise_filter_min_width = p->noise_filter_min_width; in cx23888_ir_rx_s_parameters()
770 p->resolution = clock_divider_to_resolution(rxclk_divider); in cx23888_ir_rx_s_parameters()
771 o->resolution = p->resolution; in cx23888_ir_rx_s_parameters()
773 /* FIXME - make this dependent on resolution for better performance */ in cx23888_ir_rx_s_parameters()
778 o->invert_level = p->invert_level; in cx23888_ir_rx_s_parameters()
779 atomic_set(&state->rx_invert, p->invert_level); in cx23888_ir_rx_s_parameters()
781 o->interrupt_enable = p->interrupt_enable; in cx23888_ir_rx_s_parameters()
782 o->enable = p->enable; in cx23888_ir_rx_s_parameters()
783 if (p->enable) { in cx23888_ir_rx_s_parameters()
786 spin_lock_irqsave(&state->rx_kfifo_lock, flags); in cx23888_ir_rx_s_parameters()
787 kfifo_reset(&state->rx_kfifo); in cx23888_ir_rx_s_parameters()
789 spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); in cx23888_ir_rx_s_parameters()
790 if (p->interrupt_enable) in cx23888_ir_rx_s_parameters()
792 control_rx_enable(dev, p->enable); in cx23888_ir_rx_s_parameters()
795 mutex_unlock(&state->rx_params_lock); in cx23888_ir_rx_s_parameters()
800 static int cx23888_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count, in cx23888_ir_tx_write() argument
803 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_tx_write()
804 struct cx23885_dev *dev = state->dev; in cx23888_ir_tx_write()
811 static int cx23888_ir_tx_g_parameters(struct v4l2_subdev *sd, in cx23888_ir_tx_g_parameters() argument
814 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_tx_g_parameters()
815 mutex_lock(&state->tx_params_lock); in cx23888_ir_tx_g_parameters()
816 memcpy(p, &state->tx_params, sizeof(struct v4l2_subdev_ir_parameters)); in cx23888_ir_tx_g_parameters()
817 mutex_unlock(&state->tx_params_lock); in cx23888_ir_tx_g_parameters()
821 static int cx23888_ir_tx_shutdown(struct v4l2_subdev *sd) in cx23888_ir_tx_shutdown() argument
823 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_tx_shutdown()
824 struct cx23885_dev *dev = state->dev; in cx23888_ir_tx_shutdown()
826 mutex_lock(&state->tx_params_lock); in cx23888_ir_tx_shutdown()
834 state->tx_params.shutdown = true; in cx23888_ir_tx_shutdown()
836 mutex_unlock(&state->tx_params_lock); in cx23888_ir_tx_shutdown()
840 static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd, in cx23888_ir_tx_s_parameters() argument
843 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_tx_s_parameters()
844 struct cx23885_dev *dev = state->dev; in cx23888_ir_tx_s_parameters()
845 struct v4l2_subdev_ir_parameters *o = &state->tx_params; in cx23888_ir_tx_s_parameters()
848 if (p->shutdown) in cx23888_ir_tx_s_parameters()
849 return cx23888_ir_tx_shutdown(sd); in cx23888_ir_tx_s_parameters()
851 if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH) in cx23888_ir_tx_s_parameters()
852 return -ENOSYS; in cx23888_ir_tx_s_parameters()
854 mutex_lock(&state->tx_params_lock); in cx23888_ir_tx_s_parameters()
856 o->shutdown = p->shutdown; in cx23888_ir_tx_s_parameters()
858 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; in cx23888_ir_tx_s_parameters()
860 o->bytes_per_data_element = p->bytes_per_data_element in cx23888_ir_tx_s_parameters()
867 control_tx_modulation_enable(dev, p->modulation); in cx23888_ir_tx_s_parameters()
868 o->modulation = p->modulation; in cx23888_ir_tx_s_parameters()
870 if (p->modulation) { in cx23888_ir_tx_s_parameters()
871 p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq, in cx23888_ir_tx_s_parameters()
873 o->carrier_freq = p->carrier_freq; in cx23888_ir_tx_s_parameters()
875 p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle); in cx23888_ir_tx_s_parameters()
876 o->duty_cycle = p->duty_cycle; in cx23888_ir_tx_s_parameters()
878 p->max_pulse_width = in cx23888_ir_tx_s_parameters()
881 p->max_pulse_width = in cx23888_ir_tx_s_parameters()
882 txclk_tx_s_max_pulse_width(dev, p->max_pulse_width, in cx23888_ir_tx_s_parameters()
885 o->max_pulse_width = p->max_pulse_width; in cx23888_ir_tx_s_parameters()
886 atomic_set(&state->txclk_divider, txclk_divider); in cx23888_ir_tx_s_parameters()
888 p->resolution = clock_divider_to_resolution(txclk_divider); in cx23888_ir_tx_s_parameters()
889 o->resolution = p->resolution; in cx23888_ir_tx_s_parameters()
891 /* FIXME - make this dependent on resolution for better performance */ in cx23888_ir_tx_s_parameters()
894 control_tx_polarity_invert(dev, p->invert_carrier_sense); in cx23888_ir_tx_s_parameters()
895 o->invert_carrier_sense = p->invert_carrier_sense; in cx23888_ir_tx_s_parameters()
897 control_tx_level_invert(dev, p->invert_level); in cx23888_ir_tx_s_parameters()
898 o->invert_level = p->invert_level; in cx23888_ir_tx_s_parameters()
900 o->interrupt_enable = p->interrupt_enable; in cx23888_ir_tx_s_parameters()
901 o->enable = p->enable; in cx23888_ir_tx_s_parameters()
902 if (p->enable) { in cx23888_ir_tx_s_parameters()
903 if (p->interrupt_enable) in cx23888_ir_tx_s_parameters()
905 control_tx_enable(dev, p->enable); in cx23888_ir_tx_s_parameters()
908 mutex_unlock(&state->tx_params_lock); in cx23888_ir_tx_s_parameters()
916 static int cx23888_ir_log_status(struct v4l2_subdev *sd) in cx23888_ir_log_status() argument
918 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_log_status()
919 struct cx23885_dev *dev = state->dev; in cx23888_ir_log_status()
931 v4l2_info(sd, "IR Receiver:\n"); in cx23888_ir_log_status()
932 v4l2_info(sd, "\tEnabled: %s\n", in cx23888_ir_log_status()
933 cntrl & CNTRL_RXE ? "yes" : "no"); in cx23888_ir_log_status()
934 v4l2_info(sd, "\tDemodulation from a carrier: %s\n", in cx23888_ir_log_status()
936 v4l2_info(sd, "\tFIFO: %s\n", in cx23888_ir_log_status()
955 v4l2_info(sd, "\tPulse timers' start/stop trigger: %s\n", s); in cx23888_ir_log_status()
956 v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n", in cx23888_ir_log_status()
958 v4l2_info(sd, "\tFIFO interrupt watermark: %s\n", in cx23888_ir_log_status()
960 v4l2_info(sd, "\tLoopback mode: %s\n", in cx23888_ir_log_status()
963 v4l2_info(sd, "\tExpected carrier (16 clocks): %u Hz\n", in cx23888_ir_log_status()
987 v4l2_info(sd, "\tNext carrier edge window: 16 clocks -%1d/+%1d, %u to %u Hz\n", in cx23888_ir_log_status()
990 clock_divider_to_freq(rxclk, 16 - i)); in cx23888_ir_log_status()
992 v4l2_info(sd, "\tMax measurable pulse width: %u us, %llu ns\n", in cx23888_ir_log_status()
995 v4l2_info(sd, "\tLow pass filter: %s\n", in cx23888_ir_log_status()
998 v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, %u ns\n", in cx23888_ir_log_status()
1001 v4l2_info(sd, "\tPulse width timer timed-out: %s\n", in cx23888_ir_log_status()
1002 stats & STATS_RTO ? "yes" : "no"); in cx23888_ir_log_status()
1003 v4l2_info(sd, "\tPulse width timer time-out intr: %s\n", in cx23888_ir_log_status()
1005 v4l2_info(sd, "\tFIFO overrun: %s\n", in cx23888_ir_log_status()
1006 stats & STATS_ROR ? "yes" : "no"); in cx23888_ir_log_status()
1007 v4l2_info(sd, "\tFIFO overrun interrupt: %s\n", in cx23888_ir_log_status()
1009 v4l2_info(sd, "\tBusy: %s\n", in cx23888_ir_log_status()
1010 stats & STATS_RBY ? "yes" : "no"); in cx23888_ir_log_status()
1011 v4l2_info(sd, "\tFIFO service requested: %s\n", in cx23888_ir_log_status()
1012 stats & STATS_RSR ? "yes" : "no"); in cx23888_ir_log_status()
1013 v4l2_info(sd, "\tFIFO service request interrupt: %s\n", in cx23888_ir_log_status()
1016 v4l2_info(sd, "IR Transmitter:\n"); in cx23888_ir_log_status()
1017 v4l2_info(sd, "\tEnabled: %s\n", in cx23888_ir_log_status()
1018 cntrl & CNTRL_TXE ? "yes" : "no"); in cx23888_ir_log_status()
1019 v4l2_info(sd, "\tModulation onto a carrier: %s\n", in cx23888_ir_log_status()
1021 v4l2_info(sd, "\tFIFO: %s\n", in cx23888_ir_log_status()
1023 v4l2_info(sd, "\tFIFO interrupt watermark: %s\n", in cx23888_ir_log_status()
1025 v4l2_info(sd, "\tOutput pin level inversion %s\n", in cx23888_ir_log_status()
1026 cntrl & CNTRL_IVO ? "yes" : "no"); in cx23888_ir_log_status()
1027 v4l2_info(sd, "\tCarrier polarity: %s\n", in cx23888_ir_log_status()
1031 v4l2_info(sd, "\tCarrier (16 clocks): %u Hz\n", in cx23888_ir_log_status()
1033 v4l2_info(sd, "\tCarrier duty cycle: %2u/16\n", in cx23888_ir_log_status()
1036 v4l2_info(sd, "\tMax pulse width: %u us, %llu ns\n", in cx23888_ir_log_status()
1039 v4l2_info(sd, "\tBusy: %s\n", in cx23888_ir_log_status()
1040 stats & STATS_TBY ? "yes" : "no"); in cx23888_ir_log_status()
1041 v4l2_info(sd, "\tFIFO service requested: %s\n", in cx23888_ir_log_status()
1042 stats & STATS_TSR ? "yes" : "no"); in cx23888_ir_log_status()
1043 v4l2_info(sd, "\tFIFO service request interrupt: %s\n", in cx23888_ir_log_status()
1050 static int cx23888_ir_g_register(struct v4l2_subdev *sd, in cx23888_ir_g_register() argument
1053 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_g_register()
1054 u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg; in cx23888_ir_g_register()
1057 return -EINVAL; in cx23888_ir_g_register()
1059 return -EINVAL; in cx23888_ir_g_register()
1060 reg->size = 4; in cx23888_ir_g_register()
1061 reg->val = cx23888_ir_read4(state->dev, addr); in cx23888_ir_g_register()
1065 static int cx23888_ir_s_register(struct v4l2_subdev *sd, in cx23888_ir_s_register() argument
1068 struct cx23888_ir_state *state = to_state(sd); in cx23888_ir_s_register()
1069 u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg; in cx23888_ir_s_register()
1072 return -EINVAL; in cx23888_ir_s_register()
1074 return -EINVAL; in cx23888_ir_s_register()
1075 cx23888_ir_write4(state->dev, addr, reg->val); in cx23888_ir_s_register()
1113 .carrier_freq = 36000, /* 36 kHz - RC-5, RC-6, and RC-6A carrier */
1115 /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
1116 /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
1132 .carrier_freq = 36000, /* 36 kHz - RC-5 carrier */
1133 .duty_cycle = 25, /* 25 % - RC-5 carrier */
1141 struct v4l2_subdev *sd; in cx23888_ir_probe() local
1147 return -ENOMEM; in cx23888_ir_probe()
1149 spin_lock_init(&state->rx_kfifo_lock); in cx23888_ir_probe()
1150 if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, in cx23888_ir_probe()
1153 return -ENOMEM; in cx23888_ir_probe()
1156 state->dev = dev; in cx23888_ir_probe()
1157 sd = &state->sd; in cx23888_ir_probe()
1159 v4l2_subdev_init(sd, &cx23888_ir_controller_ops); in cx23888_ir_probe()
1160 v4l2_set_subdevdata(sd, state); in cx23888_ir_probe()
1161 /* FIXME - fix the formatting of dev->v4l2_dev.name and use it */ in cx23888_ir_probe()
1162 snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name); in cx23888_ir_probe()
1163 sd->grp_id = CX23885_HW_888_IR; in cx23888_ir_probe()
1165 ret = v4l2_device_register_subdev(&dev->v4l2_dev, sd); in cx23888_ir_probe()
1168 * Ensure no interrupts arrive from '888 specific conditions, in cx23888_ir_probe()
1174 mutex_init(&state->rx_params_lock); in cx23888_ir_probe()
1176 v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params); in cx23888_ir_probe()
1178 mutex_init(&state->tx_params_lock); in cx23888_ir_probe()
1180 v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params); in cx23888_ir_probe()
1182 kfifo_free(&state->rx_kfifo); in cx23888_ir_probe()
1189 struct v4l2_subdev *sd; in cx23888_ir_remove() local
1192 sd = cx23885_find_hw(dev, CX23885_HW_888_IR); in cx23888_ir_remove()
1193 if (sd == NULL) in cx23888_ir_remove()
1194 return -ENODEV; in cx23888_ir_remove()
1196 cx23888_ir_rx_shutdown(sd); in cx23888_ir_remove()
1197 cx23888_ir_tx_shutdown(sd); in cx23888_ir_remove()
1199 state = to_state(sd); in cx23888_ir_remove()
1200 v4l2_device_unregister_subdev(sd); in cx23888_ir_remove()
1201 kfifo_free(&state->rx_kfifo); in cx23888_ir_remove()