1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2b285192aSMauro Carvalho Chehab /*
3b285192aSMauro Carvalho Chehab * cx18 gpio functions
4b285192aSMauro Carvalho Chehab *
5b285192aSMauro Carvalho Chehab * Derived from ivtv-gpio.c
6b285192aSMauro Carvalho Chehab *
7b285192aSMauro Carvalho Chehab * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
8b285192aSMauro Carvalho Chehab * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
9b285192aSMauro Carvalho Chehab */
10b285192aSMauro Carvalho Chehab
11b285192aSMauro Carvalho Chehab #include "cx18-driver.h"
12b285192aSMauro Carvalho Chehab #include "cx18-io.h"
13b285192aSMauro Carvalho Chehab #include "cx18-cards.h"
14b285192aSMauro Carvalho Chehab #include "cx18-gpio.h"
15d76231e4SMauro Carvalho Chehab #include "xc2028.h"
16b285192aSMauro Carvalho Chehab
17b285192aSMauro Carvalho Chehab /********************* GPIO stuffs *********************/
18b285192aSMauro Carvalho Chehab
19b285192aSMauro Carvalho Chehab /* GPIO registers */
20b285192aSMauro Carvalho Chehab #define CX18_REG_GPIO_IN 0xc72010
21b285192aSMauro Carvalho Chehab #define CX18_REG_GPIO_OUT1 0xc78100
22b285192aSMauro Carvalho Chehab #define CX18_REG_GPIO_DIR1 0xc78108
23b285192aSMauro Carvalho Chehab #define CX18_REG_GPIO_OUT2 0xc78104
24b285192aSMauro Carvalho Chehab #define CX18_REG_GPIO_DIR2 0xc7810c
25b285192aSMauro Carvalho Chehab
26b285192aSMauro Carvalho Chehab /*
27b285192aSMauro Carvalho Chehab * HVR-1600 GPIO pins, courtesy of Hauppauge:
28b285192aSMauro Carvalho Chehab *
29b285192aSMauro Carvalho Chehab * gpio0: zilog ir process reset pin
30b285192aSMauro Carvalho Chehab * gpio1: zilog programming pin (you should never use this)
31b285192aSMauro Carvalho Chehab * gpio12: cx24227 reset pin
32b285192aSMauro Carvalho Chehab * gpio13: cs5345 reset pin
33b285192aSMauro Carvalho Chehab */
34b285192aSMauro Carvalho Chehab
35b285192aSMauro Carvalho Chehab /*
36b285192aSMauro Carvalho Chehab * File scope utility functions
37b285192aSMauro Carvalho Chehab */
gpio_write(struct cx18 * cx)38b285192aSMauro Carvalho Chehab static void gpio_write(struct cx18 *cx)
39b285192aSMauro Carvalho Chehab {
40b285192aSMauro Carvalho Chehab u32 dir_lo = cx->gpio_dir & 0xffff;
41b285192aSMauro Carvalho Chehab u32 val_lo = cx->gpio_val & 0xffff;
42b285192aSMauro Carvalho Chehab u32 dir_hi = cx->gpio_dir >> 16;
43b285192aSMauro Carvalho Chehab u32 val_hi = cx->gpio_val >> 16;
44b285192aSMauro Carvalho Chehab
45b285192aSMauro Carvalho Chehab cx18_write_reg_expect(cx, dir_lo << 16,
46b285192aSMauro Carvalho Chehab CX18_REG_GPIO_DIR1, ~dir_lo, dir_lo);
47b285192aSMauro Carvalho Chehab cx18_write_reg_expect(cx, (dir_lo << 16) | val_lo,
48b285192aSMauro Carvalho Chehab CX18_REG_GPIO_OUT1, val_lo, dir_lo);
49b285192aSMauro Carvalho Chehab cx18_write_reg_expect(cx, dir_hi << 16,
50b285192aSMauro Carvalho Chehab CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
51b285192aSMauro Carvalho Chehab cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
52b285192aSMauro Carvalho Chehab CX18_REG_GPIO_OUT2, val_hi, dir_hi);
53b285192aSMauro Carvalho Chehab }
54b285192aSMauro Carvalho Chehab
gpio_update(struct cx18 * cx,u32 mask,u32 data)55b285192aSMauro Carvalho Chehab static void gpio_update(struct cx18 *cx, u32 mask, u32 data)
56b285192aSMauro Carvalho Chehab {
57b285192aSMauro Carvalho Chehab if (mask == 0)
58b285192aSMauro Carvalho Chehab return;
59b285192aSMauro Carvalho Chehab
60b285192aSMauro Carvalho Chehab mutex_lock(&cx->gpio_lock);
61b285192aSMauro Carvalho Chehab cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
62b285192aSMauro Carvalho Chehab gpio_write(cx);
63b285192aSMauro Carvalho Chehab mutex_unlock(&cx->gpio_lock);
64b285192aSMauro Carvalho Chehab }
65b285192aSMauro Carvalho Chehab
gpio_reset_seq(struct cx18 * cx,u32 active_lo,u32 active_hi,unsigned int assert_msecs,unsigned int recovery_msecs)66b285192aSMauro Carvalho Chehab static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi,
67b285192aSMauro Carvalho Chehab unsigned int assert_msecs,
68b285192aSMauro Carvalho Chehab unsigned int recovery_msecs)
69b285192aSMauro Carvalho Chehab {
70b285192aSMauro Carvalho Chehab u32 mask;
71b285192aSMauro Carvalho Chehab
72b285192aSMauro Carvalho Chehab mask = active_lo | active_hi;
73b285192aSMauro Carvalho Chehab if (mask == 0)
74b285192aSMauro Carvalho Chehab return;
75b285192aSMauro Carvalho Chehab
76b285192aSMauro Carvalho Chehab /*
77b285192aSMauro Carvalho Chehab * Assuming that active_hi and active_lo are a subsets of the bits in
78b285192aSMauro Carvalho Chehab * gpio_dir. Also assumes that active_lo and active_hi don't overlap
79b285192aSMauro Carvalho Chehab * in any bit position
80b285192aSMauro Carvalho Chehab */
81b285192aSMauro Carvalho Chehab
82b285192aSMauro Carvalho Chehab /* Assert */
83b285192aSMauro Carvalho Chehab gpio_update(cx, mask, ~active_lo);
84b285192aSMauro Carvalho Chehab schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs));
85b285192aSMauro Carvalho Chehab
86b285192aSMauro Carvalho Chehab /* Deassert */
87b285192aSMauro Carvalho Chehab gpio_update(cx, mask, ~active_hi);
88b285192aSMauro Carvalho Chehab schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs));
89b285192aSMauro Carvalho Chehab }
90b285192aSMauro Carvalho Chehab
91b285192aSMauro Carvalho Chehab /*
92b285192aSMauro Carvalho Chehab * GPIO Multiplexer - logical device
93b285192aSMauro Carvalho Chehab */
gpiomux_log_status(struct v4l2_subdev * sd)94b285192aSMauro Carvalho Chehab static int gpiomux_log_status(struct v4l2_subdev *sd)
95b285192aSMauro Carvalho Chehab {
96b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
97b285192aSMauro Carvalho Chehab
98b285192aSMauro Carvalho Chehab mutex_lock(&cx->gpio_lock);
99b285192aSMauro Carvalho Chehab CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
100b285192aSMauro Carvalho Chehab cx->gpio_dir, cx->gpio_val);
101b285192aSMauro Carvalho Chehab mutex_unlock(&cx->gpio_lock);
102b285192aSMauro Carvalho Chehab return 0;
103b285192aSMauro Carvalho Chehab }
104b285192aSMauro Carvalho Chehab
gpiomux_s_radio(struct v4l2_subdev * sd)105b285192aSMauro Carvalho Chehab static int gpiomux_s_radio(struct v4l2_subdev *sd)
106b285192aSMauro Carvalho Chehab {
107b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
108b285192aSMauro Carvalho Chehab
109b285192aSMauro Carvalho Chehab /*
110b285192aSMauro Carvalho Chehab * FIXME - work out the cx->active/audio_input mess - this is
111b285192aSMauro Carvalho Chehab * intended to handle the switch to radio mode and set the
112b285192aSMauro Carvalho Chehab * audio routing, but we need to update the state in cx
113b285192aSMauro Carvalho Chehab */
114b285192aSMauro Carvalho Chehab gpio_update(cx, cx->card->gpio_audio_input.mask,
115b285192aSMauro Carvalho Chehab cx->card->gpio_audio_input.radio);
116b285192aSMauro Carvalho Chehab return 0;
117b285192aSMauro Carvalho Chehab }
118b285192aSMauro Carvalho Chehab
gpiomux_s_std(struct v4l2_subdev * sd,v4l2_std_id norm)119b285192aSMauro Carvalho Chehab static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
120b285192aSMauro Carvalho Chehab {
121b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
122b285192aSMauro Carvalho Chehab u32 data;
123b285192aSMauro Carvalho Chehab
124b285192aSMauro Carvalho Chehab switch (cx->card->audio_inputs[cx->audio_input].muxer_input) {
125b285192aSMauro Carvalho Chehab case 1:
126b285192aSMauro Carvalho Chehab data = cx->card->gpio_audio_input.linein;
127b285192aSMauro Carvalho Chehab break;
128b285192aSMauro Carvalho Chehab case 0:
129b285192aSMauro Carvalho Chehab data = cx->card->gpio_audio_input.tuner;
130b285192aSMauro Carvalho Chehab break;
131b285192aSMauro Carvalho Chehab default:
132b285192aSMauro Carvalho Chehab /*
133b285192aSMauro Carvalho Chehab * FIXME - work out the cx->active/audio_input mess - this is
134b285192aSMauro Carvalho Chehab * intended to handle the switch from radio mode and set the
135b285192aSMauro Carvalho Chehab * audio routing, but we need to update the state in cx
136b285192aSMauro Carvalho Chehab */
137b285192aSMauro Carvalho Chehab data = cx->card->gpio_audio_input.tuner;
138b285192aSMauro Carvalho Chehab break;
139b285192aSMauro Carvalho Chehab }
140b285192aSMauro Carvalho Chehab gpio_update(cx, cx->card->gpio_audio_input.mask, data);
141b285192aSMauro Carvalho Chehab return 0;
142b285192aSMauro Carvalho Chehab }
143b285192aSMauro Carvalho Chehab
gpiomux_s_audio_routing(struct v4l2_subdev * sd,u32 input,u32 output,u32 config)144b285192aSMauro Carvalho Chehab static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
145b285192aSMauro Carvalho Chehab u32 input, u32 output, u32 config)
146b285192aSMauro Carvalho Chehab {
147b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
148b285192aSMauro Carvalho Chehab u32 data;
149b285192aSMauro Carvalho Chehab
150b285192aSMauro Carvalho Chehab switch (input) {
151b285192aSMauro Carvalho Chehab case 0:
152b285192aSMauro Carvalho Chehab data = cx->card->gpio_audio_input.tuner;
153b285192aSMauro Carvalho Chehab break;
154b285192aSMauro Carvalho Chehab case 1:
155b285192aSMauro Carvalho Chehab data = cx->card->gpio_audio_input.linein;
156b285192aSMauro Carvalho Chehab break;
157b285192aSMauro Carvalho Chehab case 2:
158b285192aSMauro Carvalho Chehab data = cx->card->gpio_audio_input.radio;
159b285192aSMauro Carvalho Chehab break;
160b285192aSMauro Carvalho Chehab default:
161b285192aSMauro Carvalho Chehab return -EINVAL;
162b285192aSMauro Carvalho Chehab }
163b285192aSMauro Carvalho Chehab gpio_update(cx, cx->card->gpio_audio_input.mask, data);
164b285192aSMauro Carvalho Chehab return 0;
165b285192aSMauro Carvalho Chehab }
166b285192aSMauro Carvalho Chehab
167b285192aSMauro Carvalho Chehab static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
168b285192aSMauro Carvalho Chehab .log_status = gpiomux_log_status,
169b285192aSMauro Carvalho Chehab };
170b285192aSMauro Carvalho Chehab
171b285192aSMauro Carvalho Chehab static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
172b285192aSMauro Carvalho Chehab .s_radio = gpiomux_s_radio,
173b285192aSMauro Carvalho Chehab };
174b285192aSMauro Carvalho Chehab
175b285192aSMauro Carvalho Chehab static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
176b285192aSMauro Carvalho Chehab .s_routing = gpiomux_s_audio_routing,
177b285192aSMauro Carvalho Chehab };
178b285192aSMauro Carvalho Chehab
1798774bed9SLaurent Pinchart static const struct v4l2_subdev_video_ops gpiomux_video_ops = {
1808774bed9SLaurent Pinchart .s_std = gpiomux_s_std,
1818774bed9SLaurent Pinchart };
1828774bed9SLaurent Pinchart
183b285192aSMauro Carvalho Chehab static const struct v4l2_subdev_ops gpiomux_ops = {
184b285192aSMauro Carvalho Chehab .core = &gpiomux_core_ops,
185b285192aSMauro Carvalho Chehab .tuner = &gpiomux_tuner_ops,
186b285192aSMauro Carvalho Chehab .audio = &gpiomux_audio_ops,
1878774bed9SLaurent Pinchart .video = &gpiomux_video_ops,
188b285192aSMauro Carvalho Chehab };
189b285192aSMauro Carvalho Chehab
190b285192aSMauro Carvalho Chehab /*
191b285192aSMauro Carvalho Chehab * GPIO Reset Controller - logical device
192b285192aSMauro Carvalho Chehab */
resetctrl_log_status(struct v4l2_subdev * sd)193b285192aSMauro Carvalho Chehab static int resetctrl_log_status(struct v4l2_subdev *sd)
194b285192aSMauro Carvalho Chehab {
195b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
196b285192aSMauro Carvalho Chehab
197b285192aSMauro Carvalho Chehab mutex_lock(&cx->gpio_lock);
198b285192aSMauro Carvalho Chehab CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
199b285192aSMauro Carvalho Chehab cx->gpio_dir, cx->gpio_val);
200b285192aSMauro Carvalho Chehab mutex_unlock(&cx->gpio_lock);
201b285192aSMauro Carvalho Chehab return 0;
202b285192aSMauro Carvalho Chehab }
203b285192aSMauro Carvalho Chehab
resetctrl_reset(struct v4l2_subdev * sd,u32 val)204b285192aSMauro Carvalho Chehab static int resetctrl_reset(struct v4l2_subdev *sd, u32 val)
205b285192aSMauro Carvalho Chehab {
206b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
207b285192aSMauro Carvalho Chehab const struct cx18_gpio_i2c_slave_reset *p;
208b285192aSMauro Carvalho Chehab
209b285192aSMauro Carvalho Chehab p = &cx->card->gpio_i2c_slave_reset;
210b285192aSMauro Carvalho Chehab switch (val) {
211b285192aSMauro Carvalho Chehab case CX18_GPIO_RESET_I2C:
212b285192aSMauro Carvalho Chehab gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask,
213b285192aSMauro Carvalho Chehab p->msecs_asserted, p->msecs_recovery);
214b285192aSMauro Carvalho Chehab break;
215b285192aSMauro Carvalho Chehab case CX18_GPIO_RESET_Z8F0811:
216b285192aSMauro Carvalho Chehab /*
217b285192aSMauro Carvalho Chehab * Assert timing for the Z8F0811 on HVR-1600 boards:
218b285192aSMauro Carvalho Chehab * 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to
219b285192aSMauro Carvalho Chehab * initiate
220b285192aSMauro Carvalho Chehab * 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock
221b285192aSMauro Carvalho Chehab * cycles (6,601,085 nanoseconds ~= 7 milliseconds)
222b285192aSMauro Carvalho Chehab * 3. DBG pin must be high before chip exits reset for normal
223b285192aSMauro Carvalho Chehab * operation. DBG is open drain and hopefully pulled high
224b285192aSMauro Carvalho Chehab * since we don't normally drive it (GPIO 1?) for the
225b285192aSMauro Carvalho Chehab * HVR-1600
226b285192aSMauro Carvalho Chehab * 4. Z8F0811 won't exit reset until RESET is deasserted
227b285192aSMauro Carvalho Chehab * 5. Zilog comes out of reset, loads reset vector address and
228b285192aSMauro Carvalho Chehab * executes from there. Required recovery delay unknown.
229b285192aSMauro Carvalho Chehab */
230b285192aSMauro Carvalho Chehab gpio_reset_seq(cx, p->ir_reset_mask, 0,
231b285192aSMauro Carvalho Chehab p->msecs_asserted, p->msecs_recovery);
232b285192aSMauro Carvalho Chehab break;
233b285192aSMauro Carvalho Chehab case CX18_GPIO_RESET_XC2028:
234b285192aSMauro Carvalho Chehab if (cx->card->tuners[0].tuner == TUNER_XC2028)
235b285192aSMauro Carvalho Chehab gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0,
236b285192aSMauro Carvalho Chehab 1, 1);
237b285192aSMauro Carvalho Chehab break;
238b285192aSMauro Carvalho Chehab }
239b285192aSMauro Carvalho Chehab return 0;
240b285192aSMauro Carvalho Chehab }
241b285192aSMauro Carvalho Chehab
242b285192aSMauro Carvalho Chehab static const struct v4l2_subdev_core_ops resetctrl_core_ops = {
243b285192aSMauro Carvalho Chehab .log_status = resetctrl_log_status,
244b285192aSMauro Carvalho Chehab .reset = resetctrl_reset,
245b285192aSMauro Carvalho Chehab };
246b285192aSMauro Carvalho Chehab
247b285192aSMauro Carvalho Chehab static const struct v4l2_subdev_ops resetctrl_ops = {
248b285192aSMauro Carvalho Chehab .core = &resetctrl_core_ops,
249b285192aSMauro Carvalho Chehab };
250b285192aSMauro Carvalho Chehab
251b285192aSMauro Carvalho Chehab /*
252b285192aSMauro Carvalho Chehab * External entry points
253b285192aSMauro Carvalho Chehab */
cx18_gpio_init(struct cx18 * cx)254b285192aSMauro Carvalho Chehab void cx18_gpio_init(struct cx18 *cx)
255b285192aSMauro Carvalho Chehab {
256b285192aSMauro Carvalho Chehab mutex_lock(&cx->gpio_lock);
257b285192aSMauro Carvalho Chehab cx->gpio_dir = cx->card->gpio_init.direction;
258b285192aSMauro Carvalho Chehab cx->gpio_val = cx->card->gpio_init.initial_value;
259b285192aSMauro Carvalho Chehab
260b285192aSMauro Carvalho Chehab if (cx->card->tuners[0].tuner == TUNER_XC2028) {
261b285192aSMauro Carvalho Chehab cx->gpio_dir |= 1 << cx->card->xceive_pin;
262b285192aSMauro Carvalho Chehab cx->gpio_val |= 1 << cx->card->xceive_pin;
263b285192aSMauro Carvalho Chehab }
264b285192aSMauro Carvalho Chehab
265b285192aSMauro Carvalho Chehab if (cx->gpio_dir == 0) {
266b285192aSMauro Carvalho Chehab mutex_unlock(&cx->gpio_lock);
267b285192aSMauro Carvalho Chehab return;
268b285192aSMauro Carvalho Chehab }
269b285192aSMauro Carvalho Chehab
270b285192aSMauro Carvalho Chehab CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
271b285192aSMauro Carvalho Chehab cx18_read_reg(cx, CX18_REG_GPIO_DIR1),
272b285192aSMauro Carvalho Chehab cx18_read_reg(cx, CX18_REG_GPIO_DIR2),
273b285192aSMauro Carvalho Chehab cx18_read_reg(cx, CX18_REG_GPIO_OUT1),
274b285192aSMauro Carvalho Chehab cx18_read_reg(cx, CX18_REG_GPIO_OUT2));
275b285192aSMauro Carvalho Chehab
276b285192aSMauro Carvalho Chehab gpio_write(cx);
277b285192aSMauro Carvalho Chehab mutex_unlock(&cx->gpio_lock);
278b285192aSMauro Carvalho Chehab }
279b285192aSMauro Carvalho Chehab
cx18_gpio_register(struct cx18 * cx,u32 hw)280b285192aSMauro Carvalho Chehab int cx18_gpio_register(struct cx18 *cx, u32 hw)
281b285192aSMauro Carvalho Chehab {
282b285192aSMauro Carvalho Chehab struct v4l2_subdev *sd;
283b285192aSMauro Carvalho Chehab const struct v4l2_subdev_ops *ops;
284b285192aSMauro Carvalho Chehab char *str;
285b285192aSMauro Carvalho Chehab
286b285192aSMauro Carvalho Chehab switch (hw) {
287b285192aSMauro Carvalho Chehab case CX18_HW_GPIO_MUX:
288b285192aSMauro Carvalho Chehab sd = &cx->sd_gpiomux;
289b285192aSMauro Carvalho Chehab ops = &gpiomux_ops;
290b285192aSMauro Carvalho Chehab str = "gpio-mux";
291b285192aSMauro Carvalho Chehab break;
292b285192aSMauro Carvalho Chehab case CX18_HW_GPIO_RESET_CTRL:
293b285192aSMauro Carvalho Chehab sd = &cx->sd_resetctrl;
294b285192aSMauro Carvalho Chehab ops = &resetctrl_ops;
295b285192aSMauro Carvalho Chehab str = "gpio-reset-ctrl";
296b285192aSMauro Carvalho Chehab break;
297b285192aSMauro Carvalho Chehab default:
298b285192aSMauro Carvalho Chehab return -EINVAL;
299b285192aSMauro Carvalho Chehab }
300b285192aSMauro Carvalho Chehab
301b285192aSMauro Carvalho Chehab v4l2_subdev_init(sd, ops);
302b285192aSMauro Carvalho Chehab v4l2_set_subdevdata(sd, cx);
303b285192aSMauro Carvalho Chehab snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str);
304b285192aSMauro Carvalho Chehab sd->grp_id = hw;
305b285192aSMauro Carvalho Chehab return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
306b285192aSMauro Carvalho Chehab }
307b285192aSMauro Carvalho Chehab
cx18_reset_ir_gpio(void * data)308b285192aSMauro Carvalho Chehab void cx18_reset_ir_gpio(void *data)
309b285192aSMauro Carvalho Chehab {
310*7d9326f1SYu Zhe struct cx18 *cx = to_cx18(data);
311b285192aSMauro Carvalho Chehab
312b285192aSMauro Carvalho Chehab if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0)
313b285192aSMauro Carvalho Chehab return;
314b285192aSMauro Carvalho Chehab
315b285192aSMauro Carvalho Chehab CX18_DEBUG_INFO("Resetting IR microcontroller\n");
316b285192aSMauro Carvalho Chehab
317b285192aSMauro Carvalho Chehab v4l2_subdev_call(&cx->sd_resetctrl,
318b285192aSMauro Carvalho Chehab core, reset, CX18_GPIO_RESET_Z8F0811);
319b285192aSMauro Carvalho Chehab }
320b285192aSMauro Carvalho Chehab EXPORT_SYMBOL(cx18_reset_ir_gpio);
321b285192aSMauro Carvalho Chehab /* This symbol is exported for use by lirc_pvr150 for the IR-blaster */
322b285192aSMauro Carvalho Chehab
323b285192aSMauro Carvalho Chehab /* Xceive tuner reset function */
cx18_reset_tuner_gpio(void * dev,int component,int cmd,int value)324b285192aSMauro Carvalho Chehab int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
325b285192aSMauro Carvalho Chehab {
326b285192aSMauro Carvalho Chehab struct i2c_algo_bit_data *algo = dev;
327b285192aSMauro Carvalho Chehab struct cx18_i2c_algo_callback_data *cb_data = algo->data;
328b285192aSMauro Carvalho Chehab struct cx18 *cx = cb_data->cx;
329b285192aSMauro Carvalho Chehab
330b285192aSMauro Carvalho Chehab if (cmd != XC2028_TUNER_RESET ||
331b285192aSMauro Carvalho Chehab cx->card->tuners[0].tuner != TUNER_XC2028)
332b285192aSMauro Carvalho Chehab return 0;
333b285192aSMauro Carvalho Chehab
334b285192aSMauro Carvalho Chehab CX18_DEBUG_INFO("Resetting XCeive tuner\n");
335b285192aSMauro Carvalho Chehab return v4l2_subdev_call(&cx->sd_resetctrl,
336b285192aSMauro Carvalho Chehab core, reset, CX18_GPIO_RESET_XC2028);
337b285192aSMauro Carvalho Chehab }
338