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