diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-gpio.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-gpio.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index 19253e6b8673..ceb63653c926 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c | |||
@@ -44,31 +44,57 @@ | |||
44 | * gpio13: cs5345 reset pin | 44 | * gpio13: cs5345 reset pin |
45 | */ | 45 | */ |
46 | 46 | ||
47 | static void gpio_write(struct cx18 *cx) | ||
48 | { | ||
49 | u32 dir = cx->gpio_dir; | ||
50 | u32 val = cx->gpio_val; | ||
51 | |||
52 | write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); | ||
53 | write_reg(((dir & 0xffff) << 16) | (val & 0xffff), | ||
54 | CX18_REG_GPIO_OUT1); | ||
55 | write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); | ||
56 | write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), | ||
57 | CX18_REG_GPIO_OUT2); | ||
58 | } | ||
59 | |||
47 | void cx18_gpio_init(struct cx18 *cx) | 60 | void cx18_gpio_init(struct cx18 *cx) |
48 | { | 61 | { |
49 | if (cx->card->gpio_init.direction == 0) | 62 | cx->gpio_dir = cx->card->gpio_init.direction; |
63 | cx->gpio_val = cx->card->gpio_init.initial_value; | ||
64 | |||
65 | if (cx->card->tuners[0].tuner == TUNER_XC2028) { | ||
66 | cx->gpio_dir |= 1 << cx->card->xceive_pin; | ||
67 | cx->gpio_val |= 1 << cx->card->xceive_pin; | ||
68 | } | ||
69 | |||
70 | if (cx->gpio_dir == 0) | ||
50 | return; | 71 | return; |
51 | 72 | ||
52 | CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n", | 73 | CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", |
53 | read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1)); | 74 | read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), |
75 | read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); | ||
54 | 76 | ||
55 | /* init output data then direction */ | 77 | gpio_write(cx); |
56 | write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1); | ||
57 | write_reg(0, CX18_REG_GPIO_DIR2); | ||
58 | write_reg((cx->card->gpio_init.direction << 16) | | ||
59 | cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1); | ||
60 | write_reg(0, CX18_REG_GPIO_OUT2); | ||
61 | } | 78 | } |
62 | 79 | ||
63 | /* Xceive tuner reset function */ | 80 | /* Xceive tuner reset function */ |
64 | int cx18_reset_tuner_gpio(void *dev, int cmd, int value) | 81 | int cx18_reset_tuner_gpio(void *dev, int cmd, int value) |
65 | { | 82 | { |
66 | struct i2c_algo_bit_data *algo = dev; | 83 | struct i2c_algo_bit_data *algo = dev; |
67 | struct cx18 *cx = algo->data; | 84 | struct cx18_i2c_algo_callback_data *cb_data = algo->data; |
68 | /* int curdir, curout;*/ | 85 | struct cx18 *cx = cb_data->cx; |
69 | 86 | ||
70 | if (cmd != XC2028_TUNER_RESET) | 87 | if (cmd != XC2028_TUNER_RESET) |
71 | return 0; | 88 | return 0; |
72 | CX18_DEBUG_INFO("Resetting tuner\n"); | 89 | CX18_DEBUG_INFO("Resetting tuner\n"); |
90 | |||
91 | cx->gpio_val &= ~(1 << cx->card->xceive_pin); | ||
92 | |||
93 | gpio_write(cx); | ||
94 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | ||
95 | |||
96 | cx->gpio_val |= 1 << cx->card->xceive_pin; | ||
97 | gpio_write(cx); | ||
98 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | ||
73 | return 0; | 99 | return 0; |
74 | } | 100 | } |