diff options
author | Andy Walls <awalls@md.metrocast.net> | 2010-07-18 18:39:54 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-08 22:42:54 -0400 |
commit | d06d5777b211112e8355e2f5a700c6a9babfdd6f (patch) | |
tree | 294b50055c53ecc001ad99dc0d15b6243685b2fb /drivers/media/video/cx25840 | |
parent | 66752f8396f97360cafb226aa1fe230f66785c5a (diff) |
V4L/DVB: cx25840: Add s_io_pin_config core subdev ops for the CX2388[578]
Add s_io_pin_config core subdev op for the CX2388[578] AV cores.
This is complete for IR_RX, IR_TX, GPIOs 16,19-23, and IRQ_N.
It likely needs work for the I2S signal direction.
Signed-off-by: Andy Walls <awalls@md.metrocast.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx25840')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 4f908fa4da08..46a046d6405e 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -144,6 +144,158 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp | |||
144 | 144 | ||
145 | /* ----------------------------------------------------------------------- */ | 145 | /* ----------------------------------------------------------------------- */ |
146 | 146 | ||
147 | static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n, | ||
148 | struct v4l2_subdev_io_pin_config *p) | ||
149 | { | ||
150 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
151 | int i; | ||
152 | u32 pin_ctrl; | ||
153 | u8 gpio_oe, gpio_data, strength; | ||
154 | |||
155 | pin_ctrl = cx25840_read4(client, 0x120); | ||
156 | gpio_oe = cx25840_read(client, 0x160); | ||
157 | gpio_data = cx25840_read(client, 0x164); | ||
158 | |||
159 | for (i = 0; i < n; i++) { | ||
160 | strength = p[i].strength; | ||
161 | if (strength > CX25840_PIN_DRIVE_FAST) | ||
162 | strength = CX25840_PIN_DRIVE_FAST; | ||
163 | |||
164 | switch (p[i].pin) { | ||
165 | case CX23885_PIN_IRQ_N_GPIO16: | ||
166 | if (p[i].function != CX23885_PAD_IRQ_N) { | ||
167 | /* GPIO16 */ | ||
168 | pin_ctrl &= ~(0x1 << 25); | ||
169 | } else { | ||
170 | /* IRQ_N */ | ||
171 | if (p[i].flags & | ||
172 | (V4L2_SUBDEV_IO_PIN_DISABLE | | ||
173 | V4L2_SUBDEV_IO_PIN_INPUT)) { | ||
174 | pin_ctrl &= ~(0x1 << 25); | ||
175 | } else { | ||
176 | pin_ctrl |= (0x1 << 25); | ||
177 | } | ||
178 | if (p[i].flags & | ||
179 | V4L2_SUBDEV_IO_PIN_ACTIVE_LOW) { | ||
180 | pin_ctrl &= ~(0x1 << 24); | ||
181 | } else { | ||
182 | pin_ctrl |= (0x1 << 24); | ||
183 | } | ||
184 | } | ||
185 | break; | ||
186 | case CX23885_PIN_IR_RX_GPIO19: | ||
187 | if (p[i].function != CX23885_PAD_GPIO19) { | ||
188 | /* IR_RX */ | ||
189 | gpio_oe |= (0x1 << 0); | ||
190 | pin_ctrl &= ~(0x3 << 18); | ||
191 | pin_ctrl |= (strength << 18); | ||
192 | } else { | ||
193 | /* GPIO19 */ | ||
194 | gpio_oe &= ~(0x1 << 0); | ||
195 | if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) { | ||
196 | gpio_data &= ~(0x1 << 0); | ||
197 | gpio_data |= ((p[i].value & 0x1) << 0); | ||
198 | } | ||
199 | pin_ctrl &= ~(0x3 << 12); | ||
200 | pin_ctrl |= (strength << 12); | ||
201 | } | ||
202 | break; | ||
203 | case CX23885_PIN_IR_TX_GPIO20: | ||
204 | if (p[i].function != CX23885_PAD_GPIO20) { | ||
205 | /* IR_TX */ | ||
206 | gpio_oe |= (0x1 << 1); | ||
207 | if (p[i].flags & V4L2_SUBDEV_IO_PIN_DISABLE) | ||
208 | pin_ctrl &= ~(0x1 << 10); | ||
209 | else | ||
210 | pin_ctrl |= (0x1 << 10); | ||
211 | pin_ctrl &= ~(0x3 << 18); | ||
212 | pin_ctrl |= (strength << 18); | ||
213 | } else { | ||
214 | /* GPIO20 */ | ||
215 | gpio_oe &= ~(0x1 << 1); | ||
216 | if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) { | ||
217 | gpio_data &= ~(0x1 << 1); | ||
218 | gpio_data |= ((p[i].value & 0x1) << 1); | ||
219 | } | ||
220 | pin_ctrl &= ~(0x3 << 12); | ||
221 | pin_ctrl |= (strength << 12); | ||
222 | } | ||
223 | break; | ||
224 | case CX23885_PIN_I2S_SDAT_GPIO21: | ||
225 | if (p[i].function != CX23885_PAD_GPIO21) { | ||
226 | /* I2S_SDAT */ | ||
227 | /* TODO: Input or Output config */ | ||
228 | gpio_oe |= (0x1 << 2); | ||
229 | pin_ctrl &= ~(0x3 << 22); | ||
230 | pin_ctrl |= (strength << 22); | ||
231 | } else { | ||
232 | /* GPIO21 */ | ||
233 | gpio_oe &= ~(0x1 << 2); | ||
234 | if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) { | ||
235 | gpio_data &= ~(0x1 << 2); | ||
236 | gpio_data |= ((p[i].value & 0x1) << 2); | ||
237 | } | ||
238 | pin_ctrl &= ~(0x3 << 12); | ||
239 | pin_ctrl |= (strength << 12); | ||
240 | } | ||
241 | break; | ||
242 | case CX23885_PIN_I2S_WCLK_GPIO22: | ||
243 | if (p[i].function != CX23885_PAD_GPIO22) { | ||
244 | /* I2S_WCLK */ | ||
245 | /* TODO: Input or Output config */ | ||
246 | gpio_oe |= (0x1 << 3); | ||
247 | pin_ctrl &= ~(0x3 << 22); | ||
248 | pin_ctrl |= (strength << 22); | ||
249 | } else { | ||
250 | /* GPIO22 */ | ||
251 | gpio_oe &= ~(0x1 << 3); | ||
252 | if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) { | ||
253 | gpio_data &= ~(0x1 << 3); | ||
254 | gpio_data |= ((p[i].value & 0x1) << 3); | ||
255 | } | ||
256 | pin_ctrl &= ~(0x3 << 12); | ||
257 | pin_ctrl |= (strength << 12); | ||
258 | } | ||
259 | break; | ||
260 | case CX23885_PIN_I2S_BCLK_GPIO23: | ||
261 | if (p[i].function != CX23885_PAD_GPIO23) { | ||
262 | /* I2S_BCLK */ | ||
263 | /* TODO: Input or Output config */ | ||
264 | gpio_oe |= (0x1 << 4); | ||
265 | pin_ctrl &= ~(0x3 << 22); | ||
266 | pin_ctrl |= (strength << 22); | ||
267 | } else { | ||
268 | /* GPIO23 */ | ||
269 | gpio_oe &= ~(0x1 << 4); | ||
270 | if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) { | ||
271 | gpio_data &= ~(0x1 << 4); | ||
272 | gpio_data |= ((p[i].value & 0x1) << 4); | ||
273 | } | ||
274 | pin_ctrl &= ~(0x3 << 12); | ||
275 | pin_ctrl |= (strength << 12); | ||
276 | } | ||
277 | break; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | cx25840_write(client, 0x164, gpio_data); | ||
282 | cx25840_write(client, 0x160, gpio_oe); | ||
283 | cx25840_write4(client, 0x120, pin_ctrl); | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int common_s_io_pin_config(struct v4l2_subdev *sd, size_t n, | ||
288 | struct v4l2_subdev_io_pin_config *pincfg) | ||
289 | { | ||
290 | struct cx25840_state *state = to_state(sd); | ||
291 | |||
292 | if (is_cx2388x(state)) | ||
293 | return cx23885_s_io_pin_config(sd, n, pincfg); | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | /* ----------------------------------------------------------------------- */ | ||
298 | |||
147 | static void init_dll1(struct i2c_client *client) | 299 | static void init_dll1(struct i2c_client *client) |
148 | { | 300 | { |
149 | /* This is the Hauppauge sequence used to | 301 | /* This is the Hauppauge sequence used to |
@@ -1610,6 +1762,7 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = { | |||
1610 | .s_std = cx25840_s_std, | 1762 | .s_std = cx25840_s_std, |
1611 | .reset = cx25840_reset, | 1763 | .reset = cx25840_reset, |
1612 | .load_fw = cx25840_load_fw, | 1764 | .load_fw = cx25840_load_fw, |
1765 | .s_io_pin_config = common_s_io_pin_config, | ||
1613 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1766 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1614 | .g_register = cx25840_g_register, | 1767 | .g_register = cx25840_g_register, |
1615 | .s_register = cx25840_s_register, | 1768 | .s_register = cx25840_s_register, |