diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-03 20:05:06 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:55:49 -0400 |
commit | fec528b77f9be3e7ebb8d7c25888b0cf9fb8e8d6 (patch) | |
tree | 716d78e7b40197841af9a594728036bf27fa85bd /drivers/media/video/em28xx/em28xx-dvb.c | |
parent | 39624f7ee8eb90b61d79ab731da264959ac1879a (diff) |
[media] Add initial support for Terratec H5
Not working yet. There are some fixes at the DRX-K that are needed
for it to work.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-dvb.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 012ab8ec19cf..b8686c1eb3b6 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | DVB device driver for em28xx | 2 | DVB device driver for em28xx |
3 | 3 | ||
4 | (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | ||
6 | (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> | 6 | (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> |
7 | - Fixes for the driver to properly work with HVR-950 | 7 | - Fixes for the driver to properly work with HVR-950 |
@@ -40,6 +40,8 @@ | |||
40 | #include "s921.h" | 40 | #include "s921.h" |
41 | #include "drxd.h" | 41 | #include "drxd.h" |
42 | #include "cxd2820r.h" | 42 | #include "cxd2820r.h" |
43 | #include "tda18271c2dd.h" | ||
44 | #include "drxk.h" | ||
43 | 45 | ||
44 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); | 46 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); |
45 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 47 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
@@ -73,6 +75,10 @@ struct em28xx_dvb { | |||
73 | struct dmx_frontend fe_hw; | 75 | struct dmx_frontend fe_hw; |
74 | struct dmx_frontend fe_mem; | 76 | struct dmx_frontend fe_mem; |
75 | struct dvb_net net; | 77 | struct dvb_net net; |
78 | |||
79 | /* Due to DRX-D - probably need changes */ | ||
80 | int (*gate_ctrl)(struct dvb_frontend *, int); | ||
81 | struct semaphore pll_mutex; | ||
76 | }; | 82 | }; |
77 | 83 | ||
78 | 84 | ||
@@ -295,6 +301,78 @@ static struct drxd_config em28xx_drxd = { | |||
295 | .disable_i2c_gate_ctrl = 1, | 301 | .disable_i2c_gate_ctrl = 1, |
296 | }; | 302 | }; |
297 | 303 | ||
304 | #define TERRATEC_H5_DRXK_I2C_ADDR 0x29 | ||
305 | |||
306 | struct drxk_config terratec_h5_drxk = { | ||
307 | .adr = 0x29, | ||
308 | }; | ||
309 | |||
310 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
311 | { | ||
312 | struct em28xx_dvb *dvb = fe->sec_priv; | ||
313 | int status; | ||
314 | |||
315 | if (!dvb) | ||
316 | return -EINVAL; | ||
317 | |||
318 | if (enable) { | ||
319 | down(&dvb->pll_mutex); | ||
320 | status = dvb->gate_ctrl(fe, 1); | ||
321 | } else { | ||
322 | status = dvb->gate_ctrl(fe, 0); | ||
323 | up(&dvb->pll_mutex); | ||
324 | } | ||
325 | return status; | ||
326 | } | ||
327 | |||
328 | static void terratec_h5_init(struct em28xx *dev) | ||
329 | { | ||
330 | int i; | ||
331 | struct em28xx_reg_seq terratec_h5_init[] = { | ||
332 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
333 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
334 | {EM2874_R80_GPIO, 0xf2, 0xff, 50}, | ||
335 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
336 | { -1, -1, -1, -1}, | ||
337 | }; | ||
338 | struct em28xx_reg_seq terratec_h5_end[] = { | ||
339 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
340 | {EM2874_R80_GPIO, 0xa6, 0xff, 50}, | ||
341 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
342 | { -1, -1, -1, -1}, | ||
343 | }; | ||
344 | struct { | ||
345 | unsigned char r[4]; | ||
346 | int len; | ||
347 | } regs[] = { | ||
348 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
349 | {{ 0x01, 0x02 }, 2}, | ||
350 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
351 | {{ 0x01, 0x00 }, 2}, | ||
352 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
353 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
354 | {{ 0x01, 0x00 }, 2}, | ||
355 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
356 | {{ 0x04, 0x00 }, 2}, | ||
357 | {{ 0x00, 0x04 }, 2}, | ||
358 | {{ 0x00, 0x04, 0x00, 0x0a }, 4}, | ||
359 | {{ 0x04, 0x14 }, 2}, | ||
360 | {{ 0x04, 0x14, 0x00, 0x00 }, 4}, | ||
361 | }; | ||
362 | |||
363 | em28xx_gpio_set(dev, terratec_h5_init); | ||
364 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
365 | msleep(10); | ||
366 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | ||
367 | msleep(10); | ||
368 | |||
369 | dev->i2c_client.addr = 0x82 >> 1; | ||
370 | |||
371 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
372 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
373 | em28xx_gpio_set(dev, terratec_h5_end); | ||
374 | }; | ||
375 | |||
298 | static int mt352_terratec_xs_init(struct dvb_frontend *fe) | 376 | static int mt352_terratec_xs_init(struct dvb_frontend *fe) |
299 | { | 377 | { |
300 | /* Values extracted from a USB trace of the Terratec Windows driver */ | 378 | /* Values extracted from a USB trace of the Terratec Windows driver */ |
@@ -689,6 +767,36 @@ static int dvb_init(struct em28xx *dev) | |||
689 | } | 767 | } |
690 | } | 768 | } |
691 | break; | 769 | break; |
770 | case EM2884_BOARD_TERRATEC_H5: | ||
771 | terratec_h5_init(dev); | ||
772 | |||
773 | /* dvb->fe[1] will be DVB-C, and dvb->fe[0] will be DVB-T */ | ||
774 | dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap, &dvb->fe[1]); | ||
775 | if (!dvb->fe[0] || !dvb->fe[1]) { | ||
776 | result = -EINVAL; | ||
777 | goto out_free; | ||
778 | } | ||
779 | /* FIXME: do we need a pll semaphore? */ | ||
780 | dvb->fe[0]->sec_priv = dvb; | ||
781 | sema_init(&dvb->pll_mutex, 1); | ||
782 | dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; | ||
783 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
784 | dvb->fe[1]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
785 | dvb->fe[1]->id = 1; | ||
786 | |||
787 | /* Attach tda18271 */ | ||
788 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
789 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | ||
790 | if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap, 0x60)) { | ||
791 | result = -EINVAL; | ||
792 | goto out_free; | ||
793 | } | ||
794 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
795 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); | ||
796 | if (dvb->fe[1]->ops.i2c_gate_ctrl) | ||
797 | dvb->fe[1]->ops.i2c_gate_ctrl(dvb->fe[1], 1); | ||
798 | |||
799 | break; | ||
692 | default: | 800 | default: |
693 | em28xx_errdev("/2: The frontend of your DVB/ATSC card" | 801 | em28xx_errdev("/2: The frontend of your DVB/ATSC card" |
694 | " isn't supported yet\n"); | 802 | " isn't supported yet\n"); |