Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] em28xx: add support for Hauppauge WinTV-dualHD DVB tuner

Hauppauge WinTV-dualHD is a USB 2.0 dual DVB-T/T2/C tuner with
following components:

USB bridge: Empia EM28274 (chip id is the same as EM28174)
Demodulator: 2x Silicon Labs Si2168-B40
Tuner: 2x Silicon Labs Si2157-A30

This patch adds support only for the first tuner.

The demodulator needs firmware, available for example here:
http://palosaari.fi/linux/v4l-dvb/firmware/Si2168/Si2168-B40/4.0.11/

The demodulators sit on the same I2C bus and their addresses
are 0x64 and 0x67. The tuners are behind the demodulators and
their addresses are 0x60 and 0x63.

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

authored by

Olli Salonen and committed by
Mauro Carvalho Chehab
11a2a949 628288d0

+138
+1
Documentation/video4linux/CARDLIST.em28xx
··· 97 97 96 -> Terratec Cinergy T2 Stick HD (em28178) [eb1a:8179] 98 98 97 -> Elgato EyeTV Hybrid 2008 INT (em2884) [0fd9:0018] 99 99 98 -> PLEX PX-BCUD (em28178) [3275:0085] 100 + 99 -> Hauppauge WinTV-dualHD DVB (em28174) [2040:0265]
+58
drivers/media/usb/em28xx/em28xx-cards.c
··· 507 507 }; 508 508 509 509 /* 510 + * 2040:0265 Hauppauge WinTV-dualHD DVB 511 + * reg 0x80/0x84: 512 + * GPIO_0: Yellow LED tuner 1, 0=on, 1=off 513 + * GPIO_1: Green LED tuner 1, 0=on, 1=off 514 + * GPIO_2: Yellow LED tuner 2, 0=on, 1=off 515 + * GPIO_3: Green LED tuner 2, 0=on, 1=off 516 + * GPIO_5: Reset #2, 0=active 517 + * GPIO_6: Reset #1, 0=active 518 + */ 519 + static struct em28xx_reg_seq hauppauge_dualhd_dvb[] = { 520 + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, 521 + {0x0d, 0xff, 0xff, 200}, 522 + {0x50, 0x04, 0xff, 300}, 523 + {EM2874_R80_GPIO_P0_CTRL, 0xbf, 0xff, 100}, /* demod 1 reset */ 524 + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, 525 + {EM2874_R80_GPIO_P0_CTRL, 0xdf, 0xff, 100}, /* demod 2 reset */ 526 + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, 527 + {EM2874_R5F_TS_ENABLE, 0x44, 0xff, 50}, 528 + {EM2874_R5D_TS1_PKT_SIZE, 0x05, 0xff, 50}, 529 + {EM2874_R5E_TS2_PKT_SIZE, 0x05, 0xff, 50}, 530 + {-1, -1, -1, -1}, 531 + }; 532 + 533 + /* 510 534 * Button definitions 511 535 */ 512 536 static struct em28xx_button std_snapshot_button[] = { ··· 603 579 { 604 580 .role = EM28XX_LED_ANALOG_CAPTURING, 605 581 .gpio_reg = EM2820_R08_GPIO_CTRL, 582 + .gpio_mask = EM_GPIO_3, 583 + .inverted = 1, 584 + }, 585 + {-1, 0, 0, 0}, 586 + }; 587 + 588 + static struct em28xx_led hauppauge_dualhd_leds[] = { 589 + { 590 + .role = EM28XX_LED_DIGITAL_CAPTURING, 591 + .gpio_reg = EM2874_R80_GPIO_P0_CTRL, 592 + .gpio_mask = EM_GPIO_1, 593 + .inverted = 1, 594 + }, 595 + { 596 + .role = EM28XX_LED_DIGITAL_CAPTURING_TS2, 597 + .gpio_reg = EM2874_R80_GPIO_P0_CTRL, 606 598 .gpio_mask = EM_GPIO_3, 607 599 .inverted = 1, 608 600 }, ··· 2374 2334 .tuner_gpio = plex_px_bcud, 2375 2335 .has_dvb = 1, 2376 2336 }, 2337 + /* 2338 + * 2040:0265 Hauppauge WinTV-dualHD (DVB version). 2339 + * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157 2340 + */ 2341 + [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = { 2342 + .name = "Hauppauge WinTV-dualHD DVB", 2343 + .def_i2c_bus = 1, 2344 + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | 2345 + EM28XX_I2C_FREQ_400_KHZ, 2346 + .tuner_type = TUNER_ABSENT, 2347 + .tuner_gpio = hauppauge_dualhd_dvb, 2348 + .has_dvb = 1, 2349 + .ir_codes = RC_MAP_HAUPPAUGE, 2350 + .leds = hauppauge_dualhd_leds, 2351 + }, 2377 2352 }; 2378 2353 EXPORT_SYMBOL_GPL(em28xx_boards); 2379 2354 ··· 2512 2457 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, 2513 2458 { USB_DEVICE(0x2040, 0x651f), 2514 2459 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, 2460 + { USB_DEVICE(0x2040, 0x0265), 2461 + .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, 2515 2462 { USB_DEVICE(0x0438, 0xb002), 2516 2463 .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, 2517 2464 { USB_DEVICE(0x2001, 0xf112), ··· 2948 2891 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: 2949 2892 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: 2950 2893 case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: 2894 + case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB: 2951 2895 { 2952 2896 struct tveeprom tv; 2953 2897
+64
drivers/media/usb/em28xx/em28xx-dvb.c
··· 1883 1883 px_bcud_init(dev); 1884 1884 } 1885 1885 break; 1886 + case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB: 1887 + { 1888 + struct i2c_adapter *adapter; 1889 + struct i2c_client *client; 1890 + struct i2c_board_info info; 1891 + struct si2168_config si2168_config; 1892 + struct si2157_config si2157_config; 1893 + 1894 + /* attach demod */ 1895 + memset(&si2168_config, 0, sizeof(si2168_config)); 1896 + si2168_config.i2c_adapter = &adapter; 1897 + si2168_config.fe = &dvb->fe[0]; 1898 + si2168_config.ts_mode = SI2168_TS_SERIAL; 1899 + memset(&info, 0, sizeof(struct i2c_board_info)); 1900 + strlcpy(info.type, "si2168", I2C_NAME_SIZE); 1901 + info.addr = 0x64; 1902 + info.platform_data = &si2168_config; 1903 + request_module(info.type); 1904 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 1905 + if (client == NULL || client->dev.driver == NULL) { 1906 + result = -ENODEV; 1907 + goto out_free; 1908 + } 1909 + 1910 + if (!try_module_get(client->dev.driver->owner)) { 1911 + i2c_unregister_device(client); 1912 + result = -ENODEV; 1913 + goto out_free; 1914 + } 1915 + 1916 + dvb->i2c_client_demod = client; 1917 + 1918 + /* attach tuner */ 1919 + memset(&si2157_config, 0, sizeof(si2157_config)); 1920 + si2157_config.fe = dvb->fe[0]; 1921 + si2157_config.if_port = 1; 1922 + #ifdef CONFIG_MEDIA_CONTROLLER_DVB 1923 + si2157_config.mdev = dev->media_dev; 1924 + #endif 1925 + memset(&info, 0, sizeof(struct i2c_board_info)); 1926 + strlcpy(info.type, "si2157", I2C_NAME_SIZE); 1927 + info.addr = 0x60; 1928 + info.platform_data = &si2157_config; 1929 + request_module(info.type); 1930 + client = i2c_new_device(adapter, &info); 1931 + if (client == NULL || client->dev.driver == NULL) { 1932 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1933 + i2c_unregister_device(dvb->i2c_client_demod); 1934 + result = -ENODEV; 1935 + goto out_free; 1936 + } 1937 + 1938 + if (!try_module_get(client->dev.driver->owner)) { 1939 + i2c_unregister_device(client); 1940 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1941 + i2c_unregister_device(dvb->i2c_client_demod); 1942 + result = -ENODEV; 1943 + goto out_free; 1944 + } 1945 + 1946 + dvb->i2c_client_tuner = client; 1947 + 1948 + } 1949 + break; 1886 1950 default: 1887 1951 em28xx_errdev("/2: The frontend of your DVB/ATSC card" 1888 1952 " isn't supported yet\n");
+13
drivers/media/usb/em28xx/em28xx-reg.h
··· 193 193 /* em2874 registers */ 194 194 #define EM2874_R50_IR_CONFIG 0x50 195 195 #define EM2874_R51_IR 0x51 196 + #define EM2874_R5D_TS1_PKT_SIZE 0x5d 197 + #define EM2874_R5E_TS2_PKT_SIZE 0x5e 198 + /* 199 + * For both TS1 and TS2, In isochronous mode: 200 + * 0x01 188 bytes 201 + * 0x02 376 bytes 202 + * 0x03 564 bytes 203 + * 0x04 752 bytes 204 + * 0x05 940 bytes 205 + * In bulk mode: 206 + * 0x01..0xff total packet count in 188-byte 207 + */ 208 + 196 209 #define EM2874_R5F_TS_ENABLE 0x5f 197 210 198 211 /* em2874/174/84, em25xx, em276x/7x/8x GPIO registers */
+2
drivers/media/usb/em28xx/em28xx.h
··· 146 146 #define EM28178_BOARD_TERRATEC_T2_STICK_HD 96 147 147 #define EM2884_BOARD_ELGATO_EYETV_HYBRID_2008 97 148 148 #define EM28178_BOARD_PLEX_PX_BCUD 98 149 + #define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB 99 149 150 150 151 /* Limits minimum and default number of buffers */ 151 152 #define EM28XX_MIN_BUF 4 ··· 408 407 enum em28xx_led_role { 409 408 EM28XX_LED_ANALOG_CAPTURING = 0, 410 409 EM28XX_LED_DIGITAL_CAPTURING, 410 + EM28XX_LED_DIGITAL_CAPTURING_TS2, 411 411 EM28XX_LED_ILLUMINATION, 412 412 EM28XX_NUM_LED_ROLES, /* must be the last */ 413 413 };