diff options
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-cards.c')
| -rw-r--r-- | drivers/media/usb/em28xx/em28xx-cards.c | 99 |
1 files changed, 78 insertions, 21 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index c1e0dccb7408..a51cbcf429e1 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -8,16 +8,6 @@ // Mauro Carvalho Chehab <mchehab@kernel.org> // Sascha Sommer <saschasommer@freenet.de> // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. #include "em28xx.h" @@ -565,6 +555,30 @@ static struct em28xx_reg_seq hauppauge_usb_quadhd_atsc_reg_seq[] = { }; /* + * MyGica USB TV Box + * GPIO_1,0: 00=Composite audio + * 01=Tuner audio + * 10=Mute audio + * 11=FM radio? (if equipped) + * GPIO_2-6: Unused + * GPIO_7: ?? + */ +static const struct em28xx_reg_seq mygica_utv3_composite_audio_gpio[] = { + {EM2820_R08_GPIO_CTRL, 0xfc, 0xff, 0}, + { -1, -1, -1, -1}, +}; + +static const struct em28xx_reg_seq mygica_utv3_tuner_audio_gpio[] = { + {EM2820_R08_GPIO_CTRL, 0xfd, 0xff, 0}, + { -1, -1, -1, -1}, +}; + +static const struct em28xx_reg_seq mygica_utv3_suspend_gpio[] = { + {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 0}, + { -1, -1, -1, -1}, +}; + +/* * Button definitions */ static const struct em28xx_button std_snapshot_button[] = { @@ -2508,12 +2522,17 @@ const struct em28xx_board em28xx_boards[] = { .def_i2c_bus = 1, .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, - .tuner_type = TUNER_ABSENT, + .tuner_type = TUNER_SI2157, .tuner_gpio = hauppauge_dualhd_dvb, .has_dvb = 1, .has_dual_ts = 1, .ir_codes = RC_MAP_HAUPPAUGE, .leds = hauppauge_dualhd_leds, + .input = { { + .type = EM28XX_VMUX_COMPOSITE, + .vmux = TVP5150_COMPOSITE1, + .amux = EM28XX_AMUX_LINE_IN, + } }, }, /* * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Isoc. @@ -2583,6 +2602,32 @@ const struct em28xx_board em28xx_boards[] = { .tuner_gpio = hauppauge_usb_quadhd_atsc_reg_seq, .leds = hauppauge_usb_quadhd_leds, }, + /* + * eb1a:2860 MyGica UTV3 Analog USB2.0 TV Box + * Empia EM2860, Philips SAA7113, NXP TDA9801T demod, + * Tena TNF931D-DFDR1 tuner (contains NXP TDA6509A), + * ST HCF4052 demux (switches audio to line out), + * no audio over USB + */ + [EM2860_BOARD_MYGICA_UTV3] = { + .name = "MyGica UTV3 Analog USB2.0 TV Box", + .xclk = EM28XX_XCLK_IR_RC5_MODE | EM28XX_XCLK_FREQUENCY_12MHZ, + .tuner_type = TUNER_TENA_TNF_931D_DFDR1, + .ir_codes = RC_MAP_MYGICA_UTV3, + .decoder = EM28XX_SAA711X, + .suspend_gpio = mygica_utv3_suspend_gpio, + .input = { { + .type = EM28XX_VMUX_COMPOSITE, + .vmux = SAA7115_COMPOSITE0, + .amux = EM28XX_AMUX_VIDEO, + .gpio = mygica_utv3_composite_audio_gpio, + }, { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = EM28XX_AMUX_VIDEO, + .gpio = mygica_utv3_tuner_audio_gpio, + } }, + }, }; EXPORT_SYMBOL_GPL(em28xx_boards); @@ -2824,6 +2869,7 @@ static const struct em28xx_hash_table em28xx_eeprom_hash[] = { {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT}, {0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028}, {0x85dd871e, EM2882_BOARD_ZOLID_HYBRID_TV_STICK, TUNER_XC2028}, + {0x8f597549, EM2860_BOARD_MYGICA_UTV3, TUNER_TENA_TNF_931D_DFDR1}, }; /* I2C devicelist hash table for devices with generic USB IDs */ @@ -2836,6 +2882,7 @@ static const struct em28xx_hash_table em28xx_i2c_hash[] = { {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF}, {0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT}, {0x27e10080, EM2882_BOARD_ZOLID_HYBRID_TV_STICK, TUNER_XC2028}, + {0x840d0484, EM2860_BOARD_MYGICA_UTV3, TUNER_TENA_TNF_931D_DFDR1}, }; /* NOTE: introduce a separate hash table for devices with 16 bit eeproms */ @@ -3625,8 +3672,10 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, if (dev->is_audio_only) { retval = em28xx_audio_setup(dev); - if (retval) - return -ENODEV; + if (retval) { + retval = -ENODEV; + goto err_deinit_media; + } em28xx_init_extension(dev); return 0; @@ -3645,7 +3694,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, dev_err(&dev->intf->dev, "%s: em28xx_i2c_register bus 0 - error [%d]!\n", __func__, retval); - return retval; + goto err_deinit_media; } /* register i2c bus 1 */ @@ -3661,9 +3710,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, "%s: em28xx_i2c_register bus 1 - error [%d]!\n", __func__, retval); - em28xx_i2c_unregister(dev, 0); - - return retval; + goto err_unreg_i2c; } } @@ -3671,6 +3718,12 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, em28xx_card_setup(dev); return 0; + +err_unreg_i2c: + em28xx_i2c_unregister(dev, 0); +err_deinit_media: + em28xx_unregister_media_device(dev); + return retval; } static int em28xx_duplicate_dev(struct em28xx *dev) @@ -3925,6 +3978,8 @@ static int em28xx_usb_probe(struct usb_interface *intf, goto err_free; } + kref_init(&dev->ref); + dev->devno = nr; dev->model = id->driver_info; dev->alt = -1; @@ -4025,6 +4080,8 @@ static int em28xx_usb_probe(struct usb_interface *intf, } if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) { + kref_init(&dev->dev_next->ref); + dev->dev_next->ts = SECONDARY_TS; dev->dev_next->alt = -1; dev->dev_next->is_audio_only = has_vendor_audio && @@ -4079,12 +4136,8 @@ static int em28xx_usb_probe(struct usb_interface *intf, em28xx_write_reg(dev, 0x0b, 0x82); mdelay(100); } - - kref_init(&dev->dev_next->ref); } - kref_init(&dev->ref); - request_modules(dev); /* @@ -4093,6 +4146,10 @@ static int em28xx_usb_probe(struct usb_interface *intf, * topology will likely change after the load of the em28xx subdrivers. */ #ifdef CONFIG_MEDIA_CONTROLLER + /* + * No need to check the return value, the device will still be + * usable without media controller API. + */ retval = media_device_register(dev->media_dev); #endif |
