diff options
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 1 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 1 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-gpio.c | 15 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-ioctl.c | 2 |
4 files changed, 17 insertions, 2 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index e73de625225..22434aadde3 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -421,6 +421,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) | |||
421 | mutex_init(&cx->serialize_lock); | 421 | mutex_init(&cx->serialize_lock); |
422 | mutex_init(&cx->i2c_bus_lock[0]); | 422 | mutex_init(&cx->i2c_bus_lock[0]); |
423 | mutex_init(&cx->i2c_bus_lock[1]); | 423 | mutex_init(&cx->i2c_bus_lock[1]); |
424 | mutex_init(&cx->gpio_lock); | ||
424 | 425 | ||
425 | spin_lock_init(&cx->lock); | 426 | spin_lock_init(&cx->lock); |
426 | spin_lock_init(&cx->dma_reg_lock); | 427 | spin_lock_init(&cx->dma_reg_lock); |
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index b78d0e38d53..45e31b04730 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -427,6 +427,7 @@ struct cx18 { | |||
427 | /* gpio */ | 427 | /* gpio */ |
428 | u32 gpio_dir; | 428 | u32 gpio_dir; |
429 | u32 gpio_val; | 429 | u32 gpio_val; |
430 | struct mutex gpio_lock; | ||
430 | 431 | ||
431 | /* v4l2 and User settings */ | 432 | /* v4l2 and User settings */ |
432 | 433 | ||
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index 089bad6d85a..d753a40973b 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c | |||
@@ -69,6 +69,7 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) | |||
69 | /* Assuming that the masks are a subset of the bits in gpio_dir */ | 69 | /* Assuming that the masks are a subset of the bits in gpio_dir */ |
70 | 70 | ||
71 | /* Assert */ | 71 | /* Assert */ |
72 | mutex_lock(&cx->gpio_lock); | ||
72 | cx->gpio_val = | 73 | cx->gpio_val = |
73 | (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); | 74 | (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); |
74 | gpio_write(cx); | 75 | gpio_write(cx); |
@@ -79,10 +80,12 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) | |||
79 | (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); | 80 | (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); |
80 | gpio_write(cx); | 81 | gpio_write(cx); |
81 | schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); | 82 | schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); |
83 | mutex_unlock(&cx->gpio_lock); | ||
82 | } | 84 | } |
83 | 85 | ||
84 | void cx18_gpio_init(struct cx18 *cx) | 86 | void cx18_gpio_init(struct cx18 *cx) |
85 | { | 87 | { |
88 | mutex_lock(&cx->gpio_lock); | ||
86 | cx->gpio_dir = cx->card->gpio_init.direction; | 89 | cx->gpio_dir = cx->card->gpio_init.direction; |
87 | cx->gpio_val = cx->card->gpio_init.initial_value; | 90 | cx->gpio_val = cx->card->gpio_init.initial_value; |
88 | 91 | ||
@@ -91,14 +94,17 @@ void cx18_gpio_init(struct cx18 *cx) | |||
91 | cx->gpio_val |= 1 << cx->card->xceive_pin; | 94 | cx->gpio_val |= 1 << cx->card->xceive_pin; |
92 | } | 95 | } |
93 | 96 | ||
94 | if (cx->gpio_dir == 0) | 97 | if (cx->gpio_dir == 0) { |
98 | mutex_unlock(&cx->gpio_lock); | ||
95 | return; | 99 | return; |
100 | } | ||
96 | 101 | ||
97 | CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", | 102 | CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", |
98 | read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), | 103 | read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), |
99 | read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); | 104 | read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); |
100 | 105 | ||
101 | gpio_write(cx); | 106 | gpio_write(cx); |
107 | mutex_unlock(&cx->gpio_lock); | ||
102 | } | 108 | } |
103 | 109 | ||
104 | /* Xceive tuner reset function */ | 110 | /* Xceive tuner reset function */ |
@@ -112,13 +118,16 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value) | |||
112 | return 0; | 118 | return 0; |
113 | CX18_DEBUG_INFO("Resetting tuner\n"); | 119 | CX18_DEBUG_INFO("Resetting tuner\n"); |
114 | 120 | ||
121 | mutex_lock(&cx->gpio_lock); | ||
115 | cx->gpio_val &= ~(1 << cx->card->xceive_pin); | 122 | cx->gpio_val &= ~(1 << cx->card->xceive_pin); |
116 | |||
117 | gpio_write(cx); | 123 | gpio_write(cx); |
124 | mutex_unlock(&cx->gpio_lock); | ||
118 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | 125 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
119 | 126 | ||
127 | mutex_lock(&cx->gpio_lock); | ||
120 | cx->gpio_val |= 1 << cx->card->xceive_pin; | 128 | cx->gpio_val |= 1 << cx->card->xceive_pin; |
121 | gpio_write(cx); | 129 | gpio_write(cx); |
130 | mutex_unlock(&cx->gpio_lock); | ||
122 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | 131 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
123 | return 0; | 132 | return 0; |
124 | } | 133 | } |
@@ -151,8 +160,10 @@ int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) | |||
151 | return -EINVAL; | 160 | return -EINVAL; |
152 | } | 161 | } |
153 | if (mask) { | 162 | if (mask) { |
163 | mutex_lock(&cx->gpio_lock); | ||
154 | cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); | 164 | cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); |
155 | gpio_write(cx); | 165 | gpio_write(cx); |
166 | mutex_unlock(&cx->gpio_lock); | ||
156 | } | 167 | } |
157 | return 0; | 168 | return 0; |
158 | } | 169 | } |
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 6eaf77b99e9..146a4b85649 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -716,8 +716,10 @@ static int cx18_log_status(struct file *file, void *fh) | |||
716 | cx18_get_audio_input(cx, cx->audio_input, &audin); | 716 | cx18_get_audio_input(cx, cx->audio_input, &audin); |
717 | CX18_INFO("Video Input: %s\n", vidin.name); | 717 | CX18_INFO("Video Input: %s\n", vidin.name); |
718 | CX18_INFO("Audio Input: %s\n", audin.name); | 718 | CX18_INFO("Audio Input: %s\n", audin.name); |
719 | mutex_lock(&cx->gpio_lock); | ||
719 | CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", | 720 | CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", |
720 | cx->gpio_dir, cx->gpio_val); | 721 | cx->gpio_dir, cx->gpio_val); |
722 | mutex_unlock(&cx->gpio_lock); | ||
721 | CX18_INFO("Tuner: %s\n", | 723 | CX18_INFO("Tuner: %s\n", |
722 | test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); | 724 | test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); |
723 | cx2341x_log_status(&cx->params, cx->name); | 725 | cx2341x_log_status(&cx->params, cx->name); |