diff options
Diffstat (limited to 'drivers/media/usb')
41 files changed, 3276 insertions, 2730 deletions
diff --git a/drivers/media/usb/au0828/Kconfig b/drivers/media/usb/au0828/Kconfig index bfaa806633df..65fc067eb864 100644 --- a/drivers/media/usb/au0828/Kconfig +++ b/drivers/media/usb/au0828/Kconfig @@ -4,7 +4,7 @@ config VIDEO_AU0828 depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2 select I2C_ALGOBIT select VIDEO_TVEEPROM - select VIDEOBUF2_VMALLOC + select VIDEOBUF2_VMALLOC if VIDEO_V4L2 select DVB_AU8522_DTV if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT @@ -18,7 +18,8 @@ config VIDEO_AU0828 config VIDEO_AU0828_V4L2 bool "Auvitek AU0828 v4l2 analog video support" - depends on VIDEO_AU0828 && VIDEO_V4L2 + depends on VIDEO_AU0828 + depends on VIDEO_V4L2=y || VIDEO_V4L2=VIDEO_AU0828 select DVB_AU8522_V4L if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TUNER default y diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index c765d546114d..964cd7bcdd2c 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1091,8 +1091,8 @@ static int au0828_v4l2_close(struct file *filp) */ ret = v4l_enable_media_source(vdev); if (ret == 0) - v4l2_device_call_all(&dev->v4l2_dev, 0, core, - s_power, 0); + v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, + standby); dev->std_set_in_tuner_core = 0; /* When close the device, set the usb intf0 into alt0 to free diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index f3a1e5b1e57c..b51fc372ca25 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -910,9 +910,6 @@ static void cpia2_usb_disconnect(struct usb_interface *intf) wake_up_interruptible(&cam->wq_stream); } - DBG("Releasing interface\n"); - usb_driver_release_interface(&cpia2_driver, intf); - LOG("CPiA2 camera disconnected.\n"); } diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index f9ec7fedcd5b..c76b2101193c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -922,6 +922,85 @@ struct cx231xx_board cx231xx_boards[] = { .gpio = NULL, } }, }, + [CX231XX_BOARD_HAUPPAUGE_935C] = { + .name = "Hauppauge WinTV-HVR-935C", + .tuner_type = TUNER_ABSENT, + .tuner_addr = 0x60, + .tuner_gpio = RDE250_XCV_TUNER, + .tuner_sif_gpio = 0x05, + .tuner_scl_gpio = 0x1a, + .tuner_sda_gpio = 0x1b, + .decoder = CX231XX_AVDECODER, + .output_mode = OUT_MODE_VIP11, + .demod_xfer_mode = 0, + .ctl_pin_status_mask = 0xFFFFFFC4, + .agc_analog_digital_select_gpio = 0x0c, + .gpio_pin_status_mask = 0x4001000, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_1_MUX_3, + .has_dvb = 1, + .demod_addr = 0x64, /* 0xc8 >> 1 */ + .norm = V4L2_STD_PAL, + + .input = {{ + .type = CX231XX_VMUX_TELEVISION, + .vmux = CX231XX_VIN_3_1, + .amux = CX231XX_AMUX_VIDEO, + .gpio = NULL, + }, { + .type = CX231XX_VMUX_COMPOSITE1, + .vmux = CX231XX_VIN_2_1, + .amux = CX231XX_AMUX_LINE_IN, + .gpio = NULL, + }, { + .type = CX231XX_VMUX_SVIDEO, + .vmux = CX231XX_VIN_1_1 | + (CX231XX_VIN_1_2 << 8) | + CX25840_SVIDEO_ON, + .amux = CX231XX_AMUX_LINE_IN, + .gpio = NULL, + } }, + }, + [CX231XX_BOARD_HAUPPAUGE_975] = { + .name = "Hauppauge WinTV-HVR-975", + .tuner_type = TUNER_ABSENT, + .tuner_addr = 0x60, + .tuner_gpio = RDE250_XCV_TUNER, + .tuner_sif_gpio = 0x05, + .tuner_scl_gpio = 0x1a, + .tuner_sda_gpio = 0x1b, + .decoder = CX231XX_AVDECODER, + .output_mode = OUT_MODE_VIP11, + .demod_xfer_mode = 0, + .ctl_pin_status_mask = 0xFFFFFFC4, + .agc_analog_digital_select_gpio = 0x0c, + .gpio_pin_status_mask = 0x4001000, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_1_MUX_3, + .has_dvb = 1, + .demod_addr = 0x59, /* 0xb2 >> 1 */ + .demod_addr2 = 0x64, /* 0xc8 >> 1 */ + .norm = V4L2_STD_ALL, + + .input = {{ + .type = CX231XX_VMUX_TELEVISION, + .vmux = CX231XX_VIN_3_1, + .amux = CX231XX_AMUX_VIDEO, + .gpio = NULL, + }, { + .type = CX231XX_VMUX_COMPOSITE1, + .vmux = CX231XX_VIN_2_1, + .amux = CX231XX_AMUX_LINE_IN, + .gpio = NULL, + }, { + .type = CX231XX_VMUX_SVIDEO, + .vmux = CX231XX_VIN_1_1 | + (CX231XX_VIN_1_2 << 8) | + CX25840_SVIDEO_ON, + .amux = CX231XX_AMUX_LINE_IN, + .gpio = NULL, + } }, + }, }; const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); @@ -953,6 +1032,10 @@ struct usb_device_id cx231xx_id_table[] = { .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, {USB_DEVICE(0x2040, 0xb123), .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, + {USB_DEVICE(0x2040, 0xb151), + .driver_info = CX231XX_BOARD_HAUPPAUGE_935C}, + {USB_DEVICE(0x2040, 0xb150), + .driver_info = CX231XX_BOARD_HAUPPAUGE_975}, {USB_DEVICE(0x2040, 0xb130), .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, {USB_DEVICE(0x2040, 0xb131), @@ -1135,7 +1218,7 @@ static void cx231xx_config_tuner(struct cx231xx *dev) static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, u8 *eedata, int len) { - int ret = 0; + int ret; u8 start_offset = 0; int len_todo = len; u8 *eedata_cur = eedata; @@ -1211,6 +1294,8 @@ void cx231xx_card_setup(struct cx231xx *dev) case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: case CX231XX_BOARD_HAUPPAUGE_955Q: + case CX231XX_BOARD_HAUPPAUGE_935C: + case CX231XX_BOARD_HAUPPAUGE_975: { struct eeprom { struct tveeprom tvee; diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index fb5654062b1a..713029420fcf 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -53,9 +53,10 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define CX231XX_DVB_NUM_BUFS 5 #define CX231XX_DVB_MAX_PACKETSIZE 564 #define CX231XX_DVB_MAX_PACKETS 64 +#define CX231XX_DVB_MAX_FRONTENDS 2 struct cx231xx_dvb { - struct dvb_frontend *frontend; + struct dvb_frontend *frontend[CX231XX_DVB_MAX_FRONTENDS]; /* feed count management */ struct mutex lock; @@ -68,7 +69,7 @@ struct cx231xx_dvb { struct dmx_frontend fe_hw; struct dmx_frontend fe_mem; struct dvb_net net; - struct i2c_client *i2c_client_demod; + struct i2c_client *i2c_client_demod[2]; struct i2c_client *i2c_client_tuner; }; @@ -79,7 +80,7 @@ static struct s5h1432_config dvico_s5h1432_config = { .vsb_if = S5H1432_IF_4000, .inversion = S5H1432_INVERSION_OFF, .status_mode = S5H1432_DEMODLOCKING, - .mpeg_timing = S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, + .mpeg_timing = S5H1432_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, }; static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = { @@ -108,7 +109,7 @@ static struct s5h1411_config tda18271_s5h1411_config = { .qam_if = S5H1411_IF_4000, .inversion = S5H1411_INVERSION_ON, .status_mode = S5H1411_DEMODLOCKING, - .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, + .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, }; static struct s5h1411_config xc5000_s5h1411_config = { .output_mode = S5H1411_SERIAL_OUTPUT, @@ -117,7 +118,7 @@ static struct s5h1411_config xc5000_s5h1411_config = { .qam_if = S5H1411_IF_3250, .inversion = S5H1411_INVERSION_OFF, .status_mode = S5H1411_DEMODLOCKING, - .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, + .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, }; static struct lgdt3305_config hcw_lgdt3305_config = { @@ -386,17 +387,17 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) cfg.i2c_adap = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); cfg.i2c_addr = addr; - if (!dev->dvb->frontend) { + if (!dev->dvb->frontend[0]) { dev_err(dev->dev, "%s/2: dvb frontend not attached. Can't attach xc5000\n", dev->name); return -EINVAL; } - fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg); + fe = dvb_attach(xc5000_attach, dev->dvb->frontend[0], &cfg); if (!fe) { dev_err(dev->dev, "%s/2: xc5000 attach failed\n", dev->name); - dvb_frontend_detach(dev->dvb->frontend); - dev->dvb->frontend = NULL; + dvb_frontend_detach(dev->dvb->frontend[0]); + dev->dvb->frontend[0] = NULL; return -EINVAL; } @@ -408,9 +409,9 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) { - if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) { + if (dev->dvb && dev->dvb->frontend[0]) { - struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; + struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops; if (dops->set_analog_params != NULL) { struct analog_parameters params; @@ -421,7 +422,7 @@ int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) /*params.audmode = ; */ /* Set the analog parameters to set the frequency */ - dops->set_analog_params(dev->dvb->frontend, ¶ms); + dops->set_analog_params(dev->dvb->frontend[0], ¶ms); } } @@ -433,15 +434,15 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) { int status = 0; - if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) { + if (dev->dvb && dev->dvb->frontend[0]) { - struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; + struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops; if (dops->init != NULL && !dev->xc_fw_load_done) { dev_dbg(dev->dev, "Reloading firmware for XC5000\n"); - status = dops->init(dev->dvb->frontend); + status = dops->init(dev->dvb->frontend[0]); if (status == 0) { dev->xc_fw_load_done = 1; dev_dbg(dev->dev, @@ -481,17 +482,32 @@ static int register_dvb(struct cx231xx_dvb *dvb, dvb_register_media_controller(&dvb->adapter, dev->media_dev); /* Ensure all frontends negotiate bus access */ - dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; + dvb->frontend[0]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; + if (dvb->frontend[1]) + dvb->frontend[1]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; dvb->adapter.priv = dev; /* register frontend */ - result = dvb_register_frontend(&dvb->adapter, dvb->frontend); + result = dvb_register_frontend(&dvb->adapter, dvb->frontend[0]); if (result < 0) { dev_warn(dev->dev, "%s: dvb_register_frontend failed (errno = %d)\n", dev->name, result); - goto fail_frontend; + goto fail_frontend0; + } + + if (dvb->frontend[1]) { + result = dvb_register_frontend(&dvb->adapter, dvb->frontend[1]); + if (result < 0) { + dev_warn(dev->dev, + "%s: 2nd dvb_register_frontend failed (errno = %d)\n", + dev->name, result); + goto fail_frontend1; + } + + /* MFE lock */ + dvb->adapter.mfe_shared = 1; } /* register demux stuff */ @@ -569,9 +585,14 @@ fail_fe_hw: fail_dmxdev: dvb_dmx_release(&dvb->demux); fail_dmx: - dvb_unregister_frontend(dvb->frontend); -fail_frontend: - dvb_frontend_detach(dvb->frontend); + if (dvb->frontend[1]) + dvb_unregister_frontend(dvb->frontend[1]); + dvb_unregister_frontend(dvb->frontend[0]); +fail_frontend1: + if (dvb->frontend[1]) + dvb_frontend_detach(dvb->frontend[1]); +fail_frontend0: + dvb_frontend_detach(dvb->frontend[0]); dvb_unregister_adapter(&dvb->adapter); fail_adapter: return result; @@ -585,8 +606,12 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); dvb_dmxdev_release(&dvb->dmxdev); dvb_dmx_release(&dvb->demux); - dvb_unregister_frontend(dvb->frontend); - dvb_frontend_detach(dvb->frontend); + if (dvb->frontend[1]) + dvb_unregister_frontend(dvb->frontend[1]); + dvb_unregister_frontend(dvb->frontend[0]); + if (dvb->frontend[1]) + dvb_frontend_detach(dvb->frontend[1]); + dvb_frontend_detach(dvb->frontend[0]); dvb_unregister_adapter(&dvb->adapter); /* remove I2C tuner */ client = dvb->i2c_client_tuner; @@ -595,7 +620,12 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) i2c_unregister_device(client); } /* remove I2C demod */ - client = dvb->i2c_client_demod; + client = dvb->i2c_client_demod[1]; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + client = dvb->i2c_client_demod[0]; if (client) { module_put(client->dev.driver->owner); i2c_unregister_device(client); @@ -604,7 +634,7 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) static int dvb_init(struct cx231xx *dev) { - int result = 0; + int result; struct cx231xx_dvb *dvb; struct i2c_adapter *tuner_i2c; struct i2c_adapter *demod_i2c; @@ -635,11 +665,11 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_CNXT_CARRAERA: case CX231XX_BOARD_CNXT_RDE_250: - dev->dvb->frontend = dvb_attach(s5h1432_attach, + dev->dvb->frontend[0] = dvb_attach(s5h1432_attach, &dvico_s5h1432_config, demod_i2c); - if (dev->dvb->frontend == NULL) { + if (!dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach s5h1432 front end\n"); result = -EINVAL; @@ -647,9 +677,9 @@ static int dvb_init(struct cx231xx *dev) } /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; - if (!dvb_attach(xc5000_attach, dev->dvb->frontend, + if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0], tuner_i2c, &cnxt_rde250_tunerconfig)) { result = -EINVAL; @@ -660,11 +690,11 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_CNXT_SHELBY: case CX231XX_BOARD_CNXT_RDU_250: - dev->dvb->frontend = dvb_attach(s5h1411_attach, + dev->dvb->frontend[0] = dvb_attach(s5h1411_attach, &xc5000_s5h1411_config, demod_i2c); - if (dev->dvb->frontend == NULL) { + if (!dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach s5h1411 front end\n"); result = -EINVAL; @@ -672,9 +702,9 @@ static int dvb_init(struct cx231xx *dev) } /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; - if (!dvb_attach(xc5000_attach, dev->dvb->frontend, + if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0], tuner_i2c, &cnxt_rdu250_tunerconfig)) { result = -EINVAL; @@ -683,11 +713,11 @@ static int dvb_init(struct cx231xx *dev) break; case CX231XX_BOARD_CNXT_RDE_253S: - dev->dvb->frontend = dvb_attach(s5h1432_attach, + dev->dvb->frontend[0] = dvb_attach(s5h1432_attach, &dvico_s5h1432_config, demod_i2c); - if (dev->dvb->frontend == NULL) { + if (!dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach s5h1432 front end\n"); result = -EINVAL; @@ -695,9 +725,9 @@ static int dvb_init(struct cx231xx *dev) } /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; - if (!dvb_attach(tda18271_attach, dev->dvb->frontend, + if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0], 0x60, tuner_i2c, &cnxt_rde253s_tunerconfig)) { result = -EINVAL; @@ -707,11 +737,11 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_CNXT_RDU_253S: case CX231XX_BOARD_KWORLD_UB445_USB_HYBRID: - dev->dvb->frontend = dvb_attach(s5h1411_attach, + dev->dvb->frontend[0] = dvb_attach(s5h1411_attach, &tda18271_s5h1411_config, demod_i2c); - if (dev->dvb->frontend == NULL) { + if (!dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach s5h1411 front end\n"); result = -EINVAL; @@ -719,9 +749,9 @@ static int dvb_init(struct cx231xx *dev) } /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; - if (!dvb_attach(tda18271_attach, dev->dvb->frontend, + if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0], 0x60, tuner_i2c, &cnxt_rde253s_tunerconfig)) { result = -EINVAL; @@ -734,11 +764,11 @@ static int dvb_init(struct cx231xx *dev) "%s: looking for tuner / demod on i2c bus: %d\n", __func__, i2c_adapter_id(tuner_i2c)); - dev->dvb->frontend = dvb_attach(lgdt3305_attach, + dev->dvb->frontend[0] = dvb_attach(lgdt3305_attach, &hcw_lgdt3305_config, demod_i2c); - if (dev->dvb->frontend == NULL) { + if (!dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach LG3305 front end\n"); result = -EINVAL; @@ -746,9 +776,9 @@ static int dvb_init(struct cx231xx *dev) } /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; - dvb_attach(tda18271_attach, dev->dvb->frontend, + dvb_attach(tda18271_attach, dev->dvb->frontend[0], 0x60, tuner_i2c, &hcw_tda18271_config); break; @@ -761,7 +791,7 @@ static int dvb_init(struct cx231xx *dev) /* attach demod */ memset(&si2165_pdata, 0, sizeof(si2165_pdata)); - si2165_pdata.fe = &dev->dvb->frontend; + si2165_pdata.fe = &dev->dvb->frontend[0]; si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL; si2165_pdata.ref_freq_hz = 16000000; @@ -771,7 +801,7 @@ static int dvb_init(struct cx231xx *dev) info.platform_data = &si2165_pdata; request_module(info.type); client = i2c_new_device(demod_i2c, &info); - if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend == NULL) { + if (!client || !client->dev.driver || !dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach SI2165 front end\n"); result = -EINVAL; @@ -784,14 +814,14 @@ static int dvb_init(struct cx231xx *dev) goto out_free; } - dvb->i2c_client_demod = client; + dvb->i2c_client_demod[0] = client; - dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; + dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; - dvb_attach(tda18271_attach, dev->dvb->frontend, + dvb_attach(tda18271_attach, dev->dvb->frontend[0], 0x60, tuner_i2c, &hcw_tda18271_config); @@ -808,7 +838,7 @@ static int dvb_init(struct cx231xx *dev) /* attach demod */ memset(&si2165_pdata, 0, sizeof(si2165_pdata)); - si2165_pdata.fe = &dev->dvb->frontend; + si2165_pdata.fe = &dev->dvb->frontend[0]; si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT; si2165_pdata.ref_freq_hz = 24000000; @@ -818,7 +848,7 @@ static int dvb_init(struct cx231xx *dev) info.platform_data = &si2165_pdata; request_module(info.type); client = i2c_new_device(demod_i2c, &info); - if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend == NULL) { + if (!client || !client->dev.driver || !dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach SI2165 front end\n"); result = -EINVAL; @@ -831,18 +861,18 @@ static int dvb_init(struct cx231xx *dev) goto out_free; } - dvb->i2c_client_demod = client; + dvb->i2c_client_demod[0] = client; memset(&info, 0, sizeof(struct i2c_board_info)); - dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; + dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = dev->dvb->frontend; + si2157_config.fe = dev->dvb->frontend[0]; #ifdef CONFIG_MEDIA_CONTROLLER_DVB si2157_config.mdev = dev->media_dev; #endif @@ -857,14 +887,14 @@ static int dvb_init(struct cx231xx *dev) tuner_i2c, &info); if (client == NULL || client->dev.driver == NULL) { - dvb_frontend_detach(dev->dvb->frontend); + dvb_frontend_detach(dev->dvb->frontend[0]); result = -ENODEV; goto out_free; } if (!try_module_get(client->dev.driver->owner)) { i2c_unregister_device(client); - dvb_frontend_detach(dev->dvb->frontend); + dvb_frontend_detach(dev->dvb->frontend[0]); result = -ENODEV; goto out_free; } @@ -882,26 +912,26 @@ static int dvb_init(struct cx231xx *dev) memset(&info, 0, sizeof(struct i2c_board_info)); - dev->dvb->frontend = dvb_attach(lgdt3306a_attach, + dev->dvb->frontend[0] = dvb_attach(lgdt3306a_attach, &hauppauge_955q_lgdt3306a_config, demod_i2c ); - if (dev->dvb->frontend == NULL) { + if (!dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach LGDT3306A frontend.\n"); result = -EINVAL; goto out_free; } - dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; + dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = dev->dvb->frontend; + si2157_config.fe = dev->dvb->frontend[0]; #ifdef CONFIG_MEDIA_CONTROLLER_DVB si2157_config.mdev = dev->media_dev; #endif @@ -916,14 +946,14 @@ static int dvb_init(struct cx231xx *dev) tuner_i2c, &info); if (client == NULL || client->dev.driver == NULL) { - dvb_frontend_detach(dev->dvb->frontend); + dvb_frontend_detach(dev->dvb->frontend[0]); result = -ENODEV; goto out_free; } if (!try_module_get(client->dev.driver->owner)) { i2c_unregister_device(client); - dvb_frontend_detach(dev->dvb->frontend); + dvb_frontend_detach(dev->dvb->frontend[0]); result = -ENODEV; goto out_free; } @@ -940,11 +970,11 @@ static int dvb_init(struct cx231xx *dev) "%s: looking for demod on i2c bus: %d\n", __func__, i2c_adapter_id(tuner_i2c)); - dev->dvb->frontend = dvb_attach(mb86a20s_attach, + dev->dvb->frontend[0] = dvb_attach(mb86a20s_attach, &pv_mb86a20s_config, demod_i2c); - if (dev->dvb->frontend == NULL) { + if (!dev->dvb->frontend[0]) { dev_err(dev->dev, "Failed to attach mb86a20s demod\n"); result = -EINVAL; @@ -952,9 +982,9 @@ static int dvb_init(struct cx231xx *dev) } /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; - dvb_attach(tda18271_attach, dev->dvb->frontend, + dvb_attach(tda18271_attach, dev->dvb->frontend[0], 0x60, tuner_i2c, &pv_tda18271_config); break; @@ -969,7 +999,7 @@ static int dvb_init(struct cx231xx *dev) /* attach demodulator chip */ si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */ - si2168_config.fe = &dev->dvb->frontend; + si2168_config.fe = &dev->dvb->frontend[0]; si2168_config.i2c_adapter = &adapter; si2168_config.ts_clock_inv = true; @@ -991,10 +1021,10 @@ static int dvb_init(struct cx231xx *dev) goto out_free; } - dvb->i2c_client_demod = client; + dvb->i2c_client_demod[0] = client; /* attach tuner chip */ - si2157_config.fe = dev->dvb->frontend; + si2157_config.fe = dev->dvb->frontend[0]; #ifdef CONFIG_MEDIA_CONTROLLER_DVB si2157_config.mdev = dev->media_dev; #endif @@ -1010,16 +1040,16 @@ static int dvb_init(struct cx231xx *dev) client = i2c_new_device(tuner_i2c, &info); if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); + module_put(dvb->i2c_client_demod[0]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[0]); result = -ENODEV; goto out_free; } if (!try_module_get(client->dev.driver->owner)) { i2c_unregister_device(client); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); + module_put(dvb->i2c_client_demod[0]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[0]); result = -ENODEV; goto out_free; } @@ -1037,7 +1067,7 @@ static int dvb_init(struct cx231xx *dev) /* attach demodulator chip */ mn88473_config.i2c_wr_max = 16; mn88473_config.xtal = 25000000; - mn88473_config.fe = &dev->dvb->frontend; + mn88473_config.fe = &dev->dvb->frontend[0]; strlcpy(info.type, "mn88473", sizeof(info.type)); info.addr = dev->board.demod_addr; @@ -1057,24 +1087,219 @@ static int dvb_init(struct cx231xx *dev) goto out_free; } - dvb->i2c_client_demod = client; + dvb->i2c_client_demod[0] = client; /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; + dvb->frontend[0]->callback = cx231xx_tuner_callback; /* attach tuner chip */ - dvb_attach(r820t_attach, dev->dvb->frontend, + dvb_attach(r820t_attach, dev->dvb->frontend[0], tuner_i2c, &astrometa_t2hybrid_r820t_config); break; } + case CX231XX_BOARD_HAUPPAUGE_935C: + { + struct i2c_client *client; + struct i2c_adapter *adapter; + struct i2c_board_info info = {}; + struct si2157_config si2157_config = {}; + struct si2168_config si2168_config = {}; + + /* attach demodulator chip */ + si2168_config.ts_mode = SI2168_TS_SERIAL; + si2168_config.fe = &dev->dvb->frontend[0]; + si2168_config.i2c_adapter = &adapter; + si2168_config.ts_clock_inv = true; + + strlcpy(info.type, "si2168", sizeof(info.type)); + info.addr = dev->board.demod_addr; + info.platform_data = &si2168_config; + + request_module(info.type); + client = i2c_new_device(demod_i2c, &info); + if (client == NULL || client->dev.driver == NULL) { + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + dev_err(dev->dev, + "Failed to attach %s frontend.\n", info.type); + i2c_unregister_device(client); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_demod[0] = client; + dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; + + /* define general-purpose callback pointer */ + dvb->frontend[0]->callback = cx231xx_tuner_callback; + + /* attach tuner */ + si2157_config.fe = dev->dvb->frontend[0]; +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + si2157_config.mdev = dev->media_dev; +#endif + si2157_config.if_port = 1; + si2157_config.inversion = true; + + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = dev->board.tuner_addr; + info.platform_data = &si2157_config; + request_module("si2157"); + + client = i2c_new_device(adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_demod[0]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[0]); + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + dev_err(dev->dev, + "Failed to obtain %s tuner.\n", info.type); + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod[0]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[0]); + result = -ENODEV; + goto out_free; + } + + dev->cx231xx_reset_analog_tuner = NULL; + dev->dvb->i2c_client_tuner = client; + break; + } + case CX231XX_BOARD_HAUPPAUGE_975: + { + struct i2c_client *client; + struct i2c_adapter *adapter; + struct i2c_adapter *adapter2; + struct i2c_board_info info = {}; + struct si2157_config si2157_config = {}; + struct lgdt3306a_config lgdt3306a_config = {}; + struct si2168_config si2168_config = {}; + + /* attach first demodulator chip */ + lgdt3306a_config = hauppauge_955q_lgdt3306a_config; + lgdt3306a_config.fe = &dev->dvb->frontend[0]; + lgdt3306a_config.i2c_adapter = &adapter; + lgdt3306a_config.deny_i2c_rptr = 0; + + strlcpy(info.type, "lgdt3306a", sizeof(info.type)); + info.addr = dev->board.demod_addr; + info.platform_data = &lgdt3306a_config; + + request_module(info.type); + client = i2c_new_device(demod_i2c, &info); + if (client == NULL || client->dev.driver == NULL) { + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + dev_err(dev->dev, + "Failed to attach %s frontend.\n", info.type); + i2c_unregister_device(client); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_demod[0] = client; + + /* attach second demodulator chip */ + si2168_config.ts_mode = SI2168_TS_SERIAL; + si2168_config.fe = &dev->dvb->frontend[1]; + si2168_config.i2c_adapter = &adapter2; + si2168_config.ts_clock_inv = true; + + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", sizeof(info.type)); + info.addr = dev->board.demod_addr2; + info.platform_data = &si2168_config; + + request_module(info.type); + client = i2c_new_device(adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + dev_err(dev->dev, + "Failed to attach %s frontend.\n", info.type); + module_put(dvb->i2c_client_demod[0]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[0]); + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod[0]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[0]); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_demod[1] = client; + dvb->frontend[1]->id = 1; + + /* define general-purpose callback pointer */ + dvb->frontend[0]->callback = cx231xx_tuner_callback; + dvb->frontend[1]->callback = cx231xx_tuner_callback; + + /* attach tuner */ + si2157_config.fe = dev->dvb->frontend[0]; +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + si2157_config.mdev = dev->media_dev; +#endif + si2157_config.if_port = 1; + si2157_config.inversion = true; + + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = dev->board.tuner_addr; + info.platform_data = &si2157_config; + request_module("si2157"); + + client = i2c_new_device(adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_demod[1]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[1]); + module_put(dvb->i2c_client_demod[0]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[0]); + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + dev_err(dev->dev, + "Failed to obtain %s tuner.\n", info.type); + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod[1]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[1]); + module_put(dvb->i2c_client_demod[0]->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod[0]); + result = -ENODEV; + goto out_free; + } + + dev->cx231xx_reset_analog_tuner = NULL; + dvb->i2c_client_tuner = client; + + dvb->frontend[1]->tuner_priv = dvb->frontend[0]->tuner_priv; + + memcpy(&dvb->frontend[1]->ops.tuner_ops, + &dvb->frontend[0]->ops.tuner_ops, + sizeof(struct dvb_tuner_ops)); + break; + } default: dev_err(dev->dev, "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); break; } - if (NULL == dvb->frontend) { + if (!dvb->frontend[0]) { dev_err(dev->dev, "%s/2: frontend initialization failed\n", dev->name); result = -EINVAL; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 5b321b8ada3a..f7fcd733a2ca 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1941,7 +1941,7 @@ static int cx231xx_close(struct file *filp) } /* Save some power by putting tuner to sleep */ - call_all(dev, core, s_power, 0); + call_all(dev, tuner, standby); /* do this before setting alternate! */ if (dev->USE_ISO) diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 65b039cf80be..6ffa4bd96484 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -81,6 +81,8 @@ #define CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD 23 #define CX231XX_BOARD_ASTROMETA_T2HYBRID 24 #define CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO 25 +#define CX231XX_BOARD_HAUPPAUGE_935C 26 +#define CX231XX_BOARD_HAUPPAUGE_975 27 /* Limits minimum and default number of buffers */ #define CX231XX_MIN_BUF 4 @@ -343,6 +345,7 @@ struct cx231xx_board { /* demod related */ int demod_addr; + int demod_addr2; u8 demod_xfer_mode; /* 0 - Serial; 1 - parallel */ /* GPIO Pins */ diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index 0e4944b2b0f4..37053477b84d 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig @@ -15,7 +15,8 @@ config DVB_USB_V2 config DVB_USB_AF9015 tristate "Afatech AF9015 DVB-T USB2.0 support" - depends on DVB_USB_V2 + depends on DVB_USB_V2 && I2C_MUX + select REGMAP select DVB_AF9013 select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 8013659c41b1..39f9ffce3caa 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -29,6 +29,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) #define REQ_HDR_LEN 8 /* send header size */ #define ACK_HDR_LEN 2 /* rece header size */ struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret, wlen, rlen; u8 write = 1; @@ -66,23 +67,24 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) case BOOT: break; default: - dev_err(&d->udev->dev, "%s: unknown command=%d\n", - KBUILD_MODNAME, req->cmd); + dev_err(&intf->dev, "unknown cmd %d\n", req->cmd); ret = -EIO; goto error; } - /* buffer overflow check */ + /* Buffer overflow check */ if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) || - (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) { - dev_err(&d->udev->dev, "%s: too much data; cmd=%d len=%d\n", - KBUILD_MODNAME, req->cmd, req->data_len); + (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) { + dev_err(&intf->dev, "too much data, cmd %u, len %u\n", + req->cmd, req->data_len); ret = -EINVAL; goto error; } - /* write receives seq + status = 2 bytes - read receives seq + status + data = 2 + N bytes */ + /* + * Write receives seq + status = 2 bytes + * Read receives seq + status + data = 2 + N bytes + */ wlen = REQ_HDR_LEN; rlen = ACK_HDR_LEN; if (write) { @@ -96,15 +98,14 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) rlen = 0; - ret = dvb_usbv2_generic_rw_locked(d, - state->buf, wlen, state->buf, rlen); + ret = dvb_usbv2_generic_rw_locked(d, state->buf, wlen, + state->buf, rlen); if (ret) goto error; /* check status */ if (rlen && state->buf[1]) { - dev_err(&d->udev->dev, "%s: command failed=%d\n", - KBUILD_MODNAME, state->buf[1]); + dev_err(&intf->dev, "cmd failed %u\n", state->buf[1]); ret = -EIO; goto error; } @@ -118,121 +119,66 @@ error: return ret; } -static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val, - u8 len) -{ - struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, - val}; - return af9015_ctrl_msg(d, &req); -} - -static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len) -{ - struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, - val}; - return af9015_ctrl_msg(d, &req); -} - -static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) -{ - return af9015_write_regs(d, addr, &val, 1); -} - -static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) -{ - return af9015_read_regs(d, addr, val, 1); -} - static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, - u8 val) + u8 val) { struct af9015_state *state = d_to_priv(d); struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; - if (addr == state->af9013_config[0].i2c_addr || - addr == state->af9013_config[1].i2c_addr) + if (addr == state->af9013_i2c_addr[0] || + addr == state->af9013_i2c_addr[1]) req.addr_len = 3; return af9015_ctrl_msg(d, &req); } static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, - u8 *val) + u8 *val) { struct af9015_state *state = d_to_priv(d); struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; - if (addr == state->af9013_config[0].i2c_addr || - addr == state->af9013_config[1].i2c_addr) + if (addr == state->af9013_i2c_addr[0] || + addr == state->af9013_i2c_addr[1]) req.addr_len = 3; return af9015_ctrl_msg(d, &req); } -static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op) -{ - int ret; - u8 val, mask = 0x01; - - ret = af9015_read_reg(d, addr, &val); - if (ret) - return ret; - - mask <<= bit; - if (op) { - /* set bit */ - val |= mask; - } else { - /* clear bit */ - mask ^= 0xff; - val &= mask; - } - - return af9015_write_reg(d, addr, val); -} - -static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) -{ - return af9015_do_reg_bit(d, addr, bit, 1); -} - -static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) -{ - return af9015_do_reg_bit(d, addr, bit, 0); -} - static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret; u16 addr; u8 mbox, addr_len; struct req_t req; -/* -The bus lock is needed because there is two tuners both using same I2C-address. -Due to that the only way to select correct tuner is use demodulator I2C-gate. - -................................................ -. AF9015 includes integrated AF9013 demodulator. -. ____________ ____________ . ____________ -.| uC | | demod | . | tuner | -.|------------| |------------| . |------------| -.| AF9015 | | AF9013/5 | . | MXL5003 | -.| |--+----I2C-------|-----/ -----|-.-----I2C-------| | -.| | | | addr 0x38 | . | addr 0xc6 | -.|____________| | |____________| . |____________| -.................|.............................. - | ____________ ____________ - | | demod | | tuner | - | |------------| |------------| - | | AF9013 | | MXL5003 | - +----I2C-------|-----/ -----|-------I2C-------| | - | addr 0x3a | | addr 0xc6 | - |____________| |____________| -*/ + /* + * I2C multiplexing: + * There could be two tuners, both using same I2C address. Demodulator + * I2C-gate is only possibility to select correct tuner. + * + * ........................................... + * . AF9015 integrates AF9013 demodulator . + * . ____________ ____________ . ____________ + * .| USB IF | | demod |. | tuner | + * .|------------| |------------|. |------------| + * .| AF9015 | | AF9013 |. | MXL5003 | + * .| |--+--I2C-----|-----/ -----|.----I2C-----| | + * .| | | | addr 0x1c |. | addr 0x63 | + * .|____________| | |____________|. |____________| + * .................|......................... + * | ____________ ____________ + * | | demod | | tuner | + * | |------------| |------------| + * | | AF9013 | | MXL5003 | + * +--I2C-----|-----/ -----|-----I2C-----| | + * | addr 0x1d | | addr 0x63 | + * |____________| |____________| + */ if (msg[0].len == 0 || msg[0].flags & I2C_M_RD) { addr = 0x0000; @@ -243,11 +189,11 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. mbox = 0; addr_len = 1; } else if (msg[0].len == 2) { - addr = msg[0].buf[0] << 8|msg[0].buf[1] << 0; + addr = msg[0].buf[0] << 8 | msg[0].buf[1] << 0; mbox = 0; addr_len = 2; } else { - addr = msg[0].buf[0] << 8|msg[0].buf[1] << 0; + addr = msg[0].buf[0] << 8 | msg[0].buf[1] << 0; mbox = msg[0].buf[2]; addr_len = 3; } @@ -258,7 +204,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto err; } - if (msg[0].addr == state->af9013_config[0].i2c_addr) + if (msg[0].addr == state->af9013_i2c_addr[0]) req.cmd = WRITE_MEMORY; else req.cmd = WRITE_I2C; @@ -266,7 +212,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. req.addr = addr; req.mbox = mbox; req.addr_len = addr_len; - req.data_len = msg[0].len-addr_len; + req.data_len = msg[0].len - addr_len; req.data = &msg[0].buf[addr_len]; ret = af9015_ctrl_msg(d, &req); } else if (num == 2 && !(msg[0].flags & I2C_M_RD) && @@ -276,7 +222,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto err; } - if (msg[0].addr == state->af9013_config[0].i2c_addr) + if (msg[0].addr == state->af9013_i2c_addr[0]) req.cmd = READ_MEMORY; else req.cmd = READ_I2C; @@ -293,7 +239,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto err; } - if (msg[0].addr == state->af9013_config[0].i2c_addr) { + if (msg[0].addr == state->af9013_i2c_addr[0]) { ret = -EINVAL; goto err; } @@ -307,15 +253,14 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = af9015_ctrl_msg(d, &req); } else { ret = -EOPNOTSUPP; - dev_dbg(&d->udev->dev, "%s: unknown msg, num %u\n", - __func__, num); + dev_dbg(&intf->dev, "unknown msg, num %u\n", num); } if (ret) goto err; return num; err: - dev_dbg(&d->udev->dev, "%s: failed %d\n", __func__, ret); + dev_dbg(&intf->dev, "failed %d\n", ret); return ret; } @@ -331,6 +276,7 @@ static struct i2c_algorithm af9015_i2c_algo = { static int af9015_identify_state(struct dvb_usb_device *d, const char **name) { + struct usb_interface *intf = d->intf; int ret; u8 reply; struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply}; @@ -339,7 +285,7 @@ static int af9015_identify_state(struct dvb_usb_device *d, const char **name) if (ret) return ret; - dev_dbg(&d->udev->dev, "%s: reply=%02x\n", __func__, reply); + dev_dbg(&intf->dev, "reply %02x\n", reply); if (reply == 0x02) ret = WARM; @@ -350,52 +296,47 @@ static int af9015_identify_state(struct dvb_usb_device *d, const char **name) } static int af9015_download_firmware(struct dvb_usb_device *d, - const struct firmware *fw) + const struct firmware *firmware) { struct af9015_state *state = d_to_priv(d); - int i, len, remaining, ret; + struct usb_interface *intf = d->intf; + int ret, i, rem; struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; - u16 checksum = 0; - dev_dbg(&d->udev->dev, "%s:\n", __func__); + u16 checksum; - /* calc checksum */ - for (i = 0; i < fw->size; i++) - checksum += fw->data[i]; + dev_dbg(&intf->dev, "\n"); - state->firmware_size = fw->size; - state->firmware_checksum = checksum; + /* Calc checksum, we need it when copy firmware to slave demod */ + for (i = 0, checksum = 0; i < firmware->size; i++) + checksum += firmware->data[i]; - #define FW_ADDR 0x5100 /* firmware start address */ - #define LEN_MAX 55 /* max packet size */ - for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { - len = remaining; - if (len > LEN_MAX) - len = LEN_MAX; - - req.data_len = len; - req.data = (u8 *) &fw->data[fw->size - remaining]; - req.addr = FW_ADDR + fw->size - remaining; + state->firmware_size = firmware->size; + state->firmware_checksum = checksum; + #define LEN_MAX (BUF_LEN - REQ_HDR_LEN) /* Max payload size */ + for (rem = firmware->size; rem > 0; rem -= LEN_MAX) { + req.data_len = min(LEN_MAX, rem); + req.data = (u8 *)&firmware->data[firmware->size - rem]; + req.addr = 0x5100 + firmware->size - rem; ret = af9015_ctrl_msg(d, &req); if (ret) { - dev_err(&d->udev->dev, - "%s: firmware download failed=%d\n", - KBUILD_MODNAME, ret); - goto error; + dev_err(&intf->dev, "firmware download failed %d\n", + ret); + goto err; } } - /* firmware loaded, request boot */ req.cmd = BOOT; req.data_len = 0; ret = af9015_ctrl_msg(d, &req); if (ret) { - dev_err(&d->udev->dev, "%s: firmware boot failed=%d\n", - KBUILD_MODNAME, ret); - goto error; + dev_err(&intf->dev, "firmware boot failed %d\n", ret); + goto err; } -error: + return 0; +err: + dev_dbg(&intf->dev, "failed %d\n", ret); return ret; } @@ -407,6 +348,7 @@ error: static int af9015_eeprom_hash(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret, i; u8 buf[AF9015_EEPROM_SIZE]; struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, NULL}; @@ -427,24 +369,24 @@ static int af9015_eeprom_hash(struct dvb_usb_device *d) } for (i = 0; i < AF9015_EEPROM_SIZE; i += 16) - dev_dbg(&d->udev->dev, "%s: %*ph\n", __func__, 16, buf + i); + dev_dbg(&intf->dev, "%*ph\n", 16, buf + i); - dev_dbg(&d->udev->dev, "%s: eeprom sum=%.8x\n", - __func__, state->eeprom_sum); + dev_dbg(&intf->dev, "eeprom sum %.8x\n", state->eeprom_sum); return 0; err: - dev_err(&d->udev->dev, "%s: eeprom failed=%d\n", KBUILD_MODNAME, ret); + dev_dbg(&intf->dev, "failed %d\n", ret); return ret; } static int af9015_read_config(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret; u8 val, i, offset = 0; struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; - dev_dbg(&d->udev->dev, "%s:\n", __func__); + dev_dbg(&intf->dev, "\n"); /* IR remote controller */ req.addr = AF9015_EEPROM_IR_MODE; @@ -462,7 +404,7 @@ static int af9015_read_config(struct dvb_usb_device *d) goto error; state->ir_mode = val; - dev_dbg(&d->udev->dev, "%s: IR mode=%d\n", __func__, val); + dev_dbg(&intf->dev, "ir mode %02x\n", val); /* TS mode - one or two receivers */ req.addr = AF9015_EEPROM_TS_MODE; @@ -471,13 +413,9 @@ static int af9015_read_config(struct dvb_usb_device *d) goto error; state->dual_mode = val; - dev_dbg(&d->udev->dev, "%s: TS mode=%d\n", __func__, state->dual_mode); + dev_dbg(&intf->dev, "ts mode %02x\n", state->dual_mode); - /* disable 2nd adapter because we don't have PID-filters */ - if (d->udev->speed == USB_SPEED_FULL) - state->dual_mode = 0; - - state->af9013_config[0].i2c_addr = AF9015_I2C_DEMOD; + state->af9013_i2c_addr[0] = AF9015_I2C_DEMOD; if (state->dual_mode) { /* read 2nd demodulator I2C address */ @@ -486,7 +424,7 @@ static int af9015_read_config(struct dvb_usb_device *d) if (ret) goto error; - state->af9013_config[1].i2c_addr = val >> 1; + state->af9013_i2c_addr[1] = val >> 1; } for (i = 0; i < state->dual_mode + 1; i++) { @@ -499,21 +437,20 @@ static int af9015_read_config(struct dvb_usb_device *d) goto error; switch (val) { case 0: - state->af9013_config[i].clock = 28800000; + state->af9013_pdata[i].clk = 28800000; break; case 1: - state->af9013_config[i].clock = 20480000; + state->af9013_pdata[i].clk = 20480000; break; case 2: - state->af9013_config[i].clock = 28000000; + state->af9013_pdata[i].clk = 28000000; break; case 3: - state->af9013_config[i].clock = 25000000; + state->af9013_pdata[i].clk = 25000000; break; } - dev_dbg(&d->udev->dev, "%s: [%d] xtal=%d set clock=%d\n", - __func__, i, val, - state->af9013_config[i].clock); + dev_dbg(&intf->dev, "[%d] xtal %02x, clk %u\n", + i, val, state->af9013_pdata[i].clk); /* IF frequency */ req.addr = AF9015_EEPROM_IF1H + offset; @@ -521,17 +458,17 @@ static int af9015_read_config(struct dvb_usb_device *d) if (ret) goto error; - state->af9013_config[i].if_frequency = val << 8; + state->af9013_pdata[i].if_frequency = val << 8; req.addr = AF9015_EEPROM_IF1L + offset; ret = af9015_ctrl_msg(d, &req); if (ret) goto error; - state->af9013_config[i].if_frequency += val; - state->af9013_config[i].if_frequency *= 1000; - dev_dbg(&d->udev->dev, "%s: [%d] IF frequency=%d\n", __func__, - i, state->af9013_config[i].if_frequency); + state->af9013_pdata[i].if_frequency += val; + state->af9013_pdata[i].if_frequency *= 1000; + dev_dbg(&intf->dev, "[%d] if frequency %u\n", + i, state->af9013_pdata[i].if_frequency); /* MT2060 IF1 */ req.addr = AF9015_EEPROM_MT2060_IF1H + offset; @@ -544,8 +481,8 @@ static int af9015_read_config(struct dvb_usb_device *d) if (ret) goto error; state->mt2060_if1[i] += val; - dev_dbg(&d->udev->dev, "%s: [%d] MT2060 IF1=%d\n", __func__, i, - state->mt2060_if1[i]); + dev_dbg(&intf->dev, "[%d] MT2060 IF1 %u\n", + i, state->mt2060_if1[i]); /* tuner */ req.addr = AF9015_EEPROM_TUNER_ID1 + offset; @@ -561,71 +498,177 @@ static int af9015_read_config(struct dvb_usb_device *d) case AF9013_TUNER_TDA18271: case AF9013_TUNER_QT1010A: case AF9013_TUNER_TDA18218: - state->af9013_config[i].spec_inv = 1; + state->af9013_pdata[i].spec_inv = 1; break; case AF9013_TUNER_MXL5003D: case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: case AF9013_TUNER_MXL5007T: - state->af9013_config[i].spec_inv = 0; + state->af9013_pdata[i].spec_inv = 0; break; case AF9013_TUNER_MC44S803: - state->af9013_config[i].gpio[1] = AF9013_GPIO_LO; - state->af9013_config[i].spec_inv = 1; + state->af9013_pdata[i].gpio[1] = AF9013_GPIO_LO; + state->af9013_pdata[i].spec_inv = 1; break; default: - dev_err(&d->udev->dev, "%s: tuner id=%d not " \ - "supported, please report!\n", - KBUILD_MODNAME, val); + dev_err(&intf->dev, + "tuner id %02x not supported, please report!\n", + val); return -ENODEV; } - state->af9013_config[i].tuner = val; - dev_dbg(&d->udev->dev, "%s: [%d] tuner id=%d\n", - __func__, i, val); + state->af9013_pdata[i].tuner = val; + dev_dbg(&intf->dev, "[%d] tuner id %02x\n", i, val); } error: if (ret) - dev_err(&d->udev->dev, "%s: eeprom read failed=%d\n", - KBUILD_MODNAME, ret); + dev_err(&intf->dev, "eeprom read failed %d\n", ret); - /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM - content :-( Override some wrong values here. Ditto for the - AVerTV Red HD+ (A850T) device. */ + /* + * AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM + * content :-( Override some wrong values here. Ditto for the + * AVerTV Red HD+ (A850T) device. + */ if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA && - ((le16_to_cpu(d->udev->descriptor.idProduct) == - USB_PID_AVERMEDIA_A850) || - (le16_to_cpu(d->udev->descriptor.idProduct) == - USB_PID_AVERMEDIA_A850T))) { - dev_dbg(&d->udev->dev, - "%s: AverMedia A850: overriding config\n", - __func__); + ((le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) || + (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850T))) { + dev_dbg(&intf->dev, "AverMedia A850: overriding config\n"); /* disable dual mode */ state->dual_mode = 0; /* set correct IF */ - state->af9013_config[0].if_frequency = 4570000; + state->af9013_pdata[0].if_frequency = 4570000; } return ret; } static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, - struct usb_data_stream_properties *stream) + struct usb_data_stream_properties *stream) { struct dvb_usb_device *d = fe_to_d(fe); - dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, fe_to_adap(fe)->id); + struct usb_interface *intf = d->intf; + + dev_dbg(&intf->dev, "adap %u\n", fe_to_adap(fe)->id); if (d->udev->speed == USB_SPEED_FULL) - stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE; + stream->u.bulk.buffersize = 5 * 188; + + return 0; +} + +static int af9015_streaming_ctrl(struct dvb_frontend *fe, int onoff) +{ + struct dvb_usb_device *d = fe_to_d(fe); + struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; + int ret; + unsigned int utmp1, utmp2, reg1, reg2; + u8 buf[2]; + const unsigned int adap_id = fe_to_adap(fe)->id; + + dev_dbg(&intf->dev, "adap id %d, onoff %d\n", adap_id, onoff); + + if (!state->usb_ts_if_configured[adap_id]) { + dev_dbg(&intf->dev, "set usb and ts interface\n"); + + /* USB IF stream settings */ + utmp1 = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4; + utmp2 = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4; + + buf[0] = (utmp1 >> 0) & 0xff; + buf[1] = (utmp1 >> 8) & 0xff; + if (adap_id == 0) { + /* 1st USB IF (EP4) stream settings */ + reg1 = 0xdd88; + reg2 = 0xdd0c; + } else { + /* 2nd USB IF (EP5) stream settings */ + reg1 = 0xdd8a; + reg2 = 0xdd0d; + } + ret = regmap_bulk_write(state->regmap, reg1, buf, 2); + if (ret) + goto err; + ret = regmap_write(state->regmap, reg2, utmp2); + if (ret) + goto err; + + /* TS IF settings */ + if (state->dual_mode) { + utmp1 = 0x01; + utmp2 = 0x10; + } else { + utmp1 = 0x00; + utmp2 = 0x00; + } + ret = regmap_update_bits(state->regmap, 0xd50b, 0x01, utmp1); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xd520, 0x10, utmp2); + if (ret) + goto err; + + state->usb_ts_if_configured[adap_id] = true; + } + + if (adap_id == 0 && onoff) { + /* Adapter 0 stream on. EP4: clear NAK, enable, clear reset */ + ret = regmap_update_bits(state->regmap, 0xdd13, 0x20, 0x00); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xdd11, 0x20, 0x20); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xd507, 0x04, 0x00); + if (ret) + goto err; + } else if (adap_id == 1 && onoff) { + /* Adapter 1 stream on. EP5: clear NAK, enable, clear reset */ + ret = regmap_update_bits(state->regmap, 0xdd13, 0x40, 0x00); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xdd11, 0x40, 0x40); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xd50b, 0x02, 0x00); + if (ret) + goto err; + } else if (adap_id == 0 && !onoff) { + /* Adapter 0 stream off. EP4: set reset, disable, set NAK */ + ret = regmap_update_bits(state->regmap, 0xd507, 0x04, 0x04); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xdd11, 0x20, 0x00); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xdd13, 0x20, 0x20); + if (ret) + goto err; + } else if (adap_id == 1 && !onoff) { + /* Adapter 1 stream off. EP5: set reset, disable, set NAK */ + ret = regmap_update_bits(state->regmap, 0xd50b, 0x02, 0x02); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xdd11, 0x40, 0x00); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xdd13, 0x40, 0x40); + if (ret) + goto err; + } return 0; +err: + dev_dbg(&intf->dev, "failed %d\n", ret); + return ret; } static int af9015_get_adapter_count(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); + return state->dual_mode + 1; } @@ -647,7 +690,7 @@ static int af9015_af9013_set_frontend(struct dvb_frontend *fe) /* override demod callbacks for resource locking */ static int af9015_af9013_read_status(struct dvb_frontend *fe, - enum fe_status *status) + enum fe_status *status) { int ret; struct af9015_state *state = fe_to_priv(fe); @@ -729,102 +772,105 @@ static int af9015_tuner_sleep(struct dvb_frontend *fe) static int af9015_copy_firmware(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret; - u8 fw_params[4]; - u8 val, i; - struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params), - fw_params }; - dev_dbg(&d->udev->dev, "%s:\n", __func__); - - fw_params[0] = state->firmware_size >> 8; - fw_params[1] = state->firmware_size & 0xff; - fw_params[2] = state->firmware_checksum >> 8; - fw_params[3] = state->firmware_checksum & 0xff; - - ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr, - 0x98be, &val); - if (ret) - goto error; - else - dev_dbg(&d->udev->dev, "%s: firmware status=%02x\n", - __func__, val); + unsigned long timeout; + u8 val, firmware_info[4]; + struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, 4, firmware_info}; - if (val == 0x0c) /* fw is running, no need for download */ - goto exit; + dev_dbg(&intf->dev, "\n"); - /* set I2C master clock to fast (to speed up firmware copy) */ - ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */ + firmware_info[0] = (state->firmware_size >> 8) & 0xff; + firmware_info[1] = (state->firmware_size >> 0) & 0xff; + firmware_info[2] = (state->firmware_checksum >> 8) & 0xff; + firmware_info[3] = (state->firmware_checksum >> 0) & 0xff; + + /* Check whether firmware is already running */ + ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1], 0x98be, &val); if (ret) - goto error; + goto err; - msleep(50); + dev_dbg(&intf->dev, "firmware status %02x\n", val); - /* copy firmware */ - ret = af9015_ctrl_msg(d, &req); + if (val == 0x0c) + return 0; + + /* Set i2c clock to 625kHz to speed up firmware copy */ + ret = regmap_write(state->regmap, 0xd416, 0x04); if (ret) - dev_err(&d->udev->dev, "%s: firmware copy cmd failed=%d\n", - KBUILD_MODNAME, ret); + goto err; - dev_dbg(&d->udev->dev, "%s: firmware copy done\n", __func__); + /* Copy firmware from master demod to slave demod */ + ret = af9015_ctrl_msg(d, &req); + if (ret) { + dev_err(&intf->dev, "firmware copy cmd failed %d\n", ret); + goto err; + } - /* set I2C master clock back to normal */ - ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */ + /* Set i2c clock to 125kHz */ + ret = regmap_write(state->regmap, 0xd416, 0x14); if (ret) - goto error; + goto err; - /* request boot firmware */ - ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr, - 0xe205, 1); - dev_dbg(&d->udev->dev, "%s: firmware boot cmd status=%d\n", - __func__, ret); + /* Boot firmware */ + ret = af9015_write_reg_i2c(d, state->af9013_i2c_addr[1], 0xe205, 0x01); if (ret) - goto error; + goto err; - for (i = 0; i < 15; i++) { - msleep(100); + /* Poll firmware ready */ + for (val = 0x00, timeout = jiffies + msecs_to_jiffies(1000); + !time_after(jiffies, timeout) && val != 0x0c && val != 0x04;) { + msleep(20); - /* check firmware status */ - ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr, - 0x98be, &val); - dev_dbg(&d->udev->dev, "%s: firmware status cmd status=%d " \ - "firmware status=%02x\n", __func__, ret, val); + /* Check firmware status. 0c=OK, 04=fail */ + ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1], + 0x98be, &val); if (ret) - goto error; + goto err; - if (val == 0x0c || val == 0x04) /* success or fail */ - break; + dev_dbg(&intf->dev, "firmware status %02x\n", val); } + dev_dbg(&intf->dev, "firmware boot took %u ms\n", + jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - 1000)); + if (val == 0x04) { - dev_err(&d->udev->dev, "%s: firmware did not run\n", - KBUILD_MODNAME); - ret = -ETIMEDOUT; + ret = -ENODEV; + dev_err(&intf->dev, "firmware did not run\n"); + goto err; } else if (val != 0x0c) { - dev_err(&d->udev->dev, "%s: firmware boot timeout\n", - KBUILD_MODNAME); ret = -ETIMEDOUT; + dev_err(&intf->dev, "firmware boot timeout\n"); + goto err; } -error: -exit: + return 0; +err: + dev_dbg(&intf->dev, "failed %d\n", ret); return ret; } static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) { - int ret; struct af9015_state *state = adap_to_priv(adap); + struct dvb_usb_device *d = adap_to_d(adap); + struct usb_interface *intf = d->intf; + struct i2c_client *client; + int ret; + + dev_dbg(&intf->dev, "adap id %u\n", adap->id); if (adap->id == 0) { - state->af9013_config[0].ts_mode = AF9013_TS_USB; - memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4); - state->af9013_config[0].gpio[0] = AF9013_GPIO_HI; - state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON; + state->af9013_pdata[0].ts_mode = AF9013_TS_MODE_USB; + memcpy(state->af9013_pdata[0].api_version, "\x0\x1\x9\x0", 4); + state->af9013_pdata[0].gpio[0] = AF9013_GPIO_HI; + state->af9013_pdata[0].gpio[3] = AF9013_GPIO_TUNER_ON; } else if (adap->id == 1) { - state->af9013_config[1].ts_mode = AF9013_TS_SERIAL; - memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4); - state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON; - state->af9013_config[1].gpio[1] = AF9013_GPIO_LO; + state->af9013_pdata[1].ts_mode = AF9013_TS_MODE_SERIAL; + state->af9013_pdata[1].ts_output_pin = 7; + memcpy(state->af9013_pdata[1].api_version, "\x0\x1\x9\x0", 4); + state->af9013_pdata[1].gpio[0] = AF9013_GPIO_TUNER_ON; + state->af9013_pdata[1].gpio[1] = AF9013_GPIO_LO; /* copy firmware to 2nd demodulator */ if (state->dual_mode) { @@ -833,21 +879,27 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) ret = af9015_copy_firmware(adap_to_d(adap)); if (ret) { - dev_err(&adap_to_d(adap)->udev->dev, - "%s: firmware copy to 2nd " \ - "frontend failed, will " \ - "disable it\n", KBUILD_MODNAME); + dev_err(&intf->dev, + "firmware copy to 2nd frontend failed, will disable it\n"); state->dual_mode = 0; - return -ENODEV; + goto err; } } else { - return -ENODEV; + ret = -ENODEV; + goto err; } } - /* attach demodulator */ - adap->fe[0] = dvb_attach(af9013_attach, - &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap); + /* Add I2C demod */ + client = dvb_module_probe("af9013", NULL, &d->i2c_adap, + state->af9013_i2c_addr[adap->id], + &state->af9013_pdata[adap->id]); + if (!client) { + ret = -ENODEV; + goto err; + } + adap->fe[0] = state->af9013_pdata[adap->id].get_dvb_frontend(client); + state->demod_i2c_client[adap->id] = client; /* * AF9015 firmware does not like if it gets interrupted by I2C adapter @@ -857,24 +909,36 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) * those "critical" paths to keep AF9015 happy. */ if (adap->fe[0]) { - state->set_frontend[adap->id] = - adap->fe[0]->ops.set_frontend; - adap->fe[0]->ops.set_frontend = - af9015_af9013_set_frontend; - - state->read_status[adap->id] = - adap->fe[0]->ops.read_status; - adap->fe[0]->ops.read_status = - af9015_af9013_read_status; - + state->set_frontend[adap->id] = adap->fe[0]->ops.set_frontend; + adap->fe[0]->ops.set_frontend = af9015_af9013_set_frontend; + state->read_status[adap->id] = adap->fe[0]->ops.read_status; + adap->fe[0]->ops.read_status = af9015_af9013_read_status; state->init[adap->id] = adap->fe[0]->ops.init; adap->fe[0]->ops.init = af9015_af9013_init; - state->sleep[adap->id] = adap->fe[0]->ops.sleep; adap->fe[0]->ops.sleep = af9015_af9013_sleep; } - return adap->fe[0] == NULL ? -ENODEV : 0; + return 0; +err: + dev_dbg(&intf->dev, "failed %d\n", ret); + return ret; +} + +static int af9015_frontend_detach(struct dvb_usb_adapter *adap) +{ + struct af9015_state *state = adap_to_priv(adap); + struct dvb_usb_device *d = adap_to_d(adap); + struct usb_interface *intf = d->intf; + struct i2c_client *client; + + dev_dbg(&intf->dev, "adap id %u\n", adap->id); + + /* Remove I2C demod */ + client = state->demod_i2c_client[adap->id]; + dvb_module_release(client); + + return 0; } static struct mt2060_config af9015_mt2060_config = { @@ -944,64 +1008,61 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) { struct dvb_usb_device *d = adap_to_d(adap); struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; + struct i2c_client *client; + struct i2c_adapter *adapter; int ret; - dev_dbg(&d->udev->dev, "%s:\n", __func__); - switch (state->af9013_config[adap->id].tuner) { + dev_dbg(&intf->dev, "adap id %u\n", adap->id); + + client = state->demod_i2c_client[adap->id]; + adapter = state->af9013_pdata[adap->id].get_i2c_adapter(client); + + switch (state->af9013_pdata[adap->id].tuner) { case AF9013_TUNER_MT2060: case AF9013_TUNER_MT2060_2: - ret = dvb_attach(mt2060_attach, adap->fe[0], - &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config, - state->mt2060_if1[adap->id]) - == NULL ? -ENODEV : 0; + ret = dvb_attach(mt2060_attach, adap->fe[0], adapter, + &af9015_mt2060_config, + state->mt2060_if1[adap->id]) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_QT1010: case AF9013_TUNER_QT1010A: - ret = dvb_attach(qt1010_attach, adap->fe[0], - &adap_to_d(adap)->i2c_adap, - &af9015_qt1010_config) == NULL ? -ENODEV : 0; + ret = dvb_attach(qt1010_attach, adap->fe[0], adapter, + &af9015_qt1010_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_TDA18271: - ret = dvb_attach(tda18271_attach, adap->fe[0], 0x60, - &adap_to_d(adap)->i2c_adap, - &af9015_tda18271_config) == NULL ? -ENODEV : 0; + ret = dvb_attach(tda18271_attach, adap->fe[0], 0x60, adapter, + &af9015_tda18271_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_TDA18218: - ret = dvb_attach(tda18218_attach, adap->fe[0], - &adap_to_d(adap)->i2c_adap, - &af9015_tda18218_config) == NULL ? -ENODEV : 0; + ret = dvb_attach(tda18218_attach, adap->fe[0], adapter, + &af9015_tda18218_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MXL5003D: - ret = dvb_attach(mxl5005s_attach, adap->fe[0], - &adap_to_d(adap)->i2c_adap, - &af9015_mxl5003_config) == NULL ? -ENODEV : 0; + ret = dvb_attach(mxl5005s_attach, adap->fe[0], adapter, + &af9015_mxl5003_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: - ret = dvb_attach(mxl5005s_attach, adap->fe[0], - &adap_to_d(adap)->i2c_adap, - &af9015_mxl5005_config) == NULL ? -ENODEV : 0; + ret = dvb_attach(mxl5005s_attach, adap->fe[0], adapter, + &af9015_mxl5005_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_ENV77H11D5: - ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0x60, - &adap_to_d(adap)->i2c_adap, - DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; + ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0x60, adapter, + DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MC44S803: - ret = dvb_attach(mc44s803_attach, adap->fe[0], - &adap_to_d(adap)->i2c_adap, - &af9015_mc44s803_config) == NULL ? -ENODEV : 0; + ret = dvb_attach(mc44s803_attach, adap->fe[0], adapter, + &af9015_mc44s803_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MXL5007T: - ret = dvb_attach(mxl5007t_attach, adap->fe[0], - &adap_to_d(adap)->i2c_adap, - 0x60, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; + ret = dvb_attach(mxl5007t_attach, adap->fe[0], adapter, + 0x60, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_UNKNOWN: default: - dev_err(&d->udev->dev, "%s: unknown tuner id=%d\n", - KBUILD_MODNAME, - state->af9013_config[adap->id].tuner); + dev_err(&intf->dev, "unknown tuner, tuner id %02x\n", + state->af9013_pdata[adap->id].tuner); ret = -ENODEV; } @@ -1022,136 +1083,27 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) { - struct dvb_usb_device *d = adap_to_d(adap); - int ret; - dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff); - - if (onoff) - ret = af9015_set_reg_bit(d, 0xd503, 0); - else - ret = af9015_clear_reg_bit(d, 0xd503, 0); - - return ret; -} - -static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, - int onoff) -{ - struct dvb_usb_device *d = adap_to_d(adap); + struct af9015_state *state = adap_to_priv(adap); + struct af9013_platform_data *pdata = &state->af9013_pdata[adap->id]; int ret; - u8 idx; - dev_dbg(&d->udev->dev, "%s: index=%d pid=%04x onoff=%d\n", - __func__, index, pid, onoff); - - ret = af9015_write_reg(d, 0xd505, (pid & 0xff)); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xd506, (pid >> 8)); - if (ret) - goto error; - - idx = ((index & 0x1f) | (1 << 5)); - ret = af9015_write_reg(d, 0xd504, idx); + mutex_lock(&state->fe_mutex); + ret = pdata->pid_filter_ctrl(adap->fe[0], onoff); + mutex_unlock(&state->fe_mutex); -error: return ret; } -static int af9015_init_endpoint(struct dvb_usb_device *d) +static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, + u16 pid, int onoff) { - struct af9015_state *state = d_to_priv(d); + struct af9015_state *state = adap_to_priv(adap); + struct af9013_platform_data *pdata = &state->af9013_pdata[adap->id]; int ret; - u16 frame_size; - u8 packet_size; - dev_dbg(&d->udev->dev, "%s: USB speed=%d\n", __func__, d->udev->speed); - - if (d->udev->speed == USB_SPEED_FULL) { - frame_size = TS_USB11_FRAME_SIZE/4; - packet_size = TS_USB11_MAX_PACKET_SIZE/4; - } else { - frame_size = TS_USB20_FRAME_SIZE/4; - packet_size = TS_USB20_MAX_PACKET_SIZE/4; - } - - ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */ - if (ret) - goto error; - ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */ - if (ret) - goto error; - ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */ - if (ret) - goto error; - if (state->dual_mode) { - ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */ - if (ret) - goto error; - } - ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */ - if (ret) - goto error; - if (state->dual_mode) { - ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */ - if (ret) - goto error; - } - /* EP4 xfer length */ - ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd89, frame_size >> 8); - if (ret) - goto error; - /* EP5 xfer length */ - ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */ - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */ - if (ret) - goto error; - if (state->dual_mode) { - ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */ - if (ret) - goto error; - } - /* enable / disable mp2if2 */ - if (state->dual_mode) { - ret = af9015_set_reg_bit(d, 0xd50b, 0); - if (ret) - goto error; - ret = af9015_set_reg_bit(d, 0xd520, 4); - if (ret) - goto error; - } else { - ret = af9015_clear_reg_bit(d, 0xd50b, 0); - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xd520, 4); - if (ret) - goto error; - } - -error: - if (ret) - dev_err(&d->udev->dev, "%s: endpoint init failed=%d\n", - KBUILD_MODNAME, ret); + mutex_lock(&state->fe_mutex); + ret = pdata->pid_filter(adap->fe[0], index, pid, onoff); + mutex_unlock(&state->fe_mutex); return ret; } @@ -1159,17 +1111,15 @@ error: static int af9015_init(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret; - dev_dbg(&d->udev->dev, "%s:\n", __func__); + + dev_dbg(&intf->dev, "\n"); mutex_init(&state->fe_mutex); /* init RC canary */ - ret = af9015_write_reg(d, 0x98e9, 0xff); - if (ret) - goto error; - - ret = af9015_init_endpoint(d); + ret = regmap_write(state->regmap, 0x98e9, 0xff); if (ret) goto error; @@ -1184,7 +1134,7 @@ struct af9015_rc_setup { }; static char *af9015_rc_setup_match(unsigned int id, - const struct af9015_rc_setup *table) + const struct af9015_rc_setup *table) { for (; table->rc_codes; table++) if (table->id == id) @@ -1212,24 +1162,25 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { static int af9015_rc_query(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret; u8 buf[17]; /* read registers needed to detect remote controller code */ - ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); + ret = regmap_bulk_read(state->regmap, 0x98d9, buf, sizeof(buf)); if (ret) goto error; /* If any of these are non-zero, assume invalid data */ if (buf[1] || buf[2] || buf[3]) { - dev_dbg(&d->udev->dev, "%s: invalid data\n", __func__); + dev_dbg(&intf->dev, "invalid data\n"); return ret; } /* Check for repeat of previous code */ if ((state->rc_repeat != buf[6] || buf[0]) && - !memcmp(&buf[12], state->rc_last, 4)) { - dev_dbg(&d->udev->dev, "%s: key repeated\n", __func__); + !memcmp(&buf[12], state->rc_last, 4)) { + dev_dbg(&intf->dev, "key repeated\n"); rc_repeat(d->rc_dev); state->rc_repeat = buf[6]; return ret; @@ -1238,18 +1189,18 @@ static int af9015_rc_query(struct dvb_usb_device *d) /* Only process key if canary killed */ if (buf[16] != 0xff && buf[0] != 0x01) { enum rc_proto proto; - dev_dbg(&d->udev->dev, "%s: key pressed %*ph\n", - __func__, 4, buf + 12); + + dev_dbg(&intf->dev, "key pressed %*ph\n", 4, buf + 12); /* Reset the canary */ - ret = af9015_write_reg(d, 0x98e9, 0xff); + ret = regmap_write(state->regmap, 0x98e9, 0xff); if (ret) goto error; /* Remember this key */ memcpy(state->rc_last, &buf[12], 4); - if (buf[14] == (u8) ~buf[15]) { - if (buf[12] == (u8) ~buf[13]) { + if (buf[14] == (u8)~buf[15]) { + if (buf[12] == (u8)~buf[13]) { /* NEC */ state->rc_keycode = RC_SCANCODE_NEC(buf[12], buf[14]); @@ -1271,7 +1222,7 @@ static int af9015_rc_query(struct dvb_usb_device *d) } rc_keydown(d->rc_dev, proto, state->rc_keycode, 0); } else { - dev_dbg(&d->udev->dev, "%s: no key press\n", __func__); + dev_dbg(&intf->dev, "no key press\n"); /* Invalidate last keypress */ /* Not really needed, but helps with debug */ state->rc_last[2] = state->rc_last[3]; @@ -1282,8 +1233,7 @@ static int af9015_rc_query(struct dvb_usb_device *d) error: if (ret) { - dev_warn(&d->udev->dev, "%s: rc query failed=%d\n", - KBUILD_MODNAME, ret); + dev_warn(&intf->dev, "rc query failed %d\n", ret); /* allow random errors as dvb-usb will stop polling on error */ if (!state->rc_failed) @@ -1306,29 +1256,33 @@ static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) /* try to load remote based module param */ if (!rc->map_name) rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote, - af9015_rc_setup_modparam); + af9015_rc_setup_modparam); /* try to load remote based eeprom hash */ if (!rc->map_name) rc->map_name = af9015_rc_setup_match(state->eeprom_sum, - af9015_rc_setup_hashes); + af9015_rc_setup_hashes); /* try to load remote based USB iManufacturer string */ if (!rc->map_name && vid == USB_VID_AFATECH) { - /* Check USB manufacturer and product strings and try - to determine correct remote in case of chip vendor - reference IDs are used. - DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */ + /* + * Check USB manufacturer and product strings and try + * to determine correct remote in case of chip vendor + * reference IDs are used. + * DO NOT ADD ANYTHING NEW HERE. Use hashes instead. + */ char manufacturer[10]; + memset(manufacturer, 0, sizeof(manufacturer)); usb_string(d->udev, d->udev->descriptor.iManufacturer, - manufacturer, sizeof(manufacturer)); + manufacturer, sizeof(manufacturer)); if (!strcmp("MSI", manufacturer)) { - /* iManufacturer 1 MSI - iProduct 2 MSI K-VOX */ - rc->map_name = af9015_rc_setup_match( - AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, - af9015_rc_setup_modparam); + /* + * iManufacturer 1 MSI + * iProduct 2 MSI K-VOX + */ + rc->map_name = af9015_rc_setup_match(AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, + af9015_rc_setup_modparam); } } @@ -1347,15 +1301,68 @@ static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) #define af9015_get_rc_config NULL #endif -static int af9015_probe(struct usb_interface *intf, - const struct usb_device_id *id) +static int af9015_regmap_write(void *context, const void *data, size_t count) { + struct dvb_usb_device *d = context; + struct usb_interface *intf = d->intf; + int ret; + u16 reg = ((u8 *)data)[0] << 8 | ((u8 *)data)[1] << 0; + u8 *val = &((u8 *)data)[2]; + const unsigned int len = count - 2; + struct req_t req = {WRITE_MEMORY, 0, reg, 0, 0, len, val}; + + ret = af9015_ctrl_msg(d, &req); + if (ret) + goto err; + + return 0; +err: + dev_dbg(&intf->dev, "failed %d\n", ret); + return ret; +} + +static int af9015_regmap_read(void *context, const void *reg_buf, + size_t reg_size, void *val_buf, size_t val_size) +{ + struct dvb_usb_device *d = context; + struct usb_interface *intf = d->intf; + int ret; + u16 reg = ((u8 *)reg_buf)[0] << 8 | ((u8 *)reg_buf)[1] << 0; + u8 *val = &((u8 *)val_buf)[0]; + const unsigned int len = val_size; + struct req_t req = {READ_MEMORY, 0, reg, 0, 0, len, val}; + + ret = af9015_ctrl_msg(d, &req); + if (ret) + goto err; + + return 0; +err: + dev_dbg(&intf->dev, "failed %d\n", ret); + return ret; +} + +static int af9015_probe(struct dvb_usb_device *d) +{ + struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; struct usb_device *udev = interface_to_usbdev(intf); + int ret; char manufacturer[sizeof("ITE Technologies, Inc.")]; + static const struct regmap_config regmap_config = { + .reg_bits = 16, + .val_bits = 8, + }; + static const struct regmap_bus regmap_bus = { + .read = af9015_regmap_read, + .write = af9015_regmap_write, + }; + + dev_dbg(&intf->dev, "\n"); memset(manufacturer, 0, sizeof(manufacturer)); usb_string(udev, udev->descriptor.iManufacturer, - manufacturer, sizeof(manufacturer)); + manufacturer, sizeof(manufacturer)); /* * There is two devices having same ID but different chipset. One uses * AF9015 and the other IT9135 chipset. Only difference seen on lsusb @@ -1374,19 +1381,41 @@ static int af9015_probe(struct usb_interface *intf, * iProduct 2 DVB-T TV Stick */ if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) && - (le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) { + (le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) { if (!strcmp("ITE Technologies, Inc.", manufacturer)) { - dev_dbg(&udev->dev, "%s: rejecting device\n", __func__); - return -ENODEV; + ret = -ENODEV; + dev_dbg(&intf->dev, "rejecting device\n"); + goto err; } } - return dvb_usbv2_probe(intf, id); + state->regmap = regmap_init(&intf->dev, ®map_bus, d, ®map_config); + if (IS_ERR(state->regmap)) { + ret = PTR_ERR(state->regmap); + goto err; + } + + return 0; +err: + dev_dbg(&intf->dev, "failed %d\n", ret); + return ret; } -/* interface 0 is used by DVB-T receiver and - interface 1 is for remote controller (HID) */ -static struct dvb_usb_device_properties af9015_props = { +static void af9015_disconnect(struct dvb_usb_device *d) +{ + struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; + + dev_dbg(&intf->dev, "\n"); + + regmap_exit(state->regmap); +} + +/* + * Interface 0 is used by DVB-T receiver and + * interface 1 is for remote controller (HID) + */ +static const struct dvb_usb_device_properties af9015_props = { .driver_name = KBUILD_MODNAME, .owner = THIS_MODULE, .adapter_nr = adapter_nr, @@ -1395,6 +1424,8 @@ static struct dvb_usb_device_properties af9015_props = { .generic_bulk_ctrl_endpoint = 0x02, .generic_bulk_ctrl_endpoint_response = 0x81, + .probe = af9015_probe, + .disconnect = af9015_disconnect, .identify_state = af9015_identify_state, .firmware = AF9015_FIRMWARE, .download_firmware = af9015_download_firmware, @@ -1402,10 +1433,12 @@ static struct dvb_usb_device_properties af9015_props = { .i2c_algo = &af9015_i2c_algo, .read_config = af9015_read_config, .frontend_attach = af9015_af9013_frontend_attach, + .frontend_detach = af9015_frontend_detach, .tuner_attach = af9015_tuner_attach, .init = af9015_init, .get_rc_config = af9015_get_rc_config, .get_stream_config = af9015_get_stream_config, + .streaming_ctrl = af9015_streaming_ctrl, .get_adapter_count = af9015_get_adapter_count, .adapter = { @@ -1416,9 +1449,15 @@ static struct dvb_usb_device_properties af9015_props = { .pid_filter = af9015_pid_filter, .pid_filter_ctrl = af9015_pid_filter_ctrl, - .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE), + .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188), }, { - .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE), + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = af9015_pid_filter, + .pid_filter_ctrl = af9015_pid_filter_ctrl, + + .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188), }, }, }; @@ -1509,7 +1548,7 @@ MODULE_DEVICE_TABLE(usb, af9015_id_table); static struct usb_driver af9015_usb_driver = { .name = KBUILD_MODNAME, .id_table = af9015_id_table, - .probe = af9015_probe, + .probe = dvb_usbv2_probe, .disconnect = dvb_usbv2_disconnect, .suspend = dvb_usbv2_suspend, .resume = dvb_usbv2_resume, diff --git a/drivers/media/usb/dvb-usb-v2/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h index 3a9d9815ab7a..ad2b045cc39c 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.h +++ b/drivers/media/usb/dvb-usb-v2/af9015.h @@ -21,6 +21,7 @@ #define AF9015_H #include <linux/hash.h> +#include <linux/regmap.h> #include "dvb_usb.h" #include "af9013.h" #include "dvb-pll.h" @@ -34,19 +35,6 @@ #define AF9015_FIRMWARE "dvb-usb-af9015.fw" -/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0. - We use smaller - about 1/4 from the original, 5 and 87. */ -#define TS_PACKET_SIZE 188 - -#define TS_USB20_PACKET_COUNT 87 -#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT) - -#define TS_USB11_PACKET_COUNT 5 -#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT) - -#define TS_USB20_MAX_PACKET_SIZE 512 -#define TS_USB11_MAX_PACKET_SIZE 64 - #define AF9015_I2C_EEPROM 0x50 #define AF9015_I2C_DEMOD 0x1c #define AF9015_USB_TIMEOUT 2000 @@ -113,6 +101,7 @@ enum af9015_ir_mode { #define BUF_LEN 63 struct af9015_state { + struct regmap *regmap; u8 buf[BUF_LEN]; /* bulk USB control message */ u8 ir_mode; u8 rc_repeat; @@ -125,7 +114,10 @@ struct af9015_state { u16 firmware_size; u16 firmware_checksum; u32 eeprom_sum; - struct af9013_config af9013_config[2]; + struct af9013_platform_data af9013_pdata[2]; + struct i2c_client *demod_i2c_client[2]; + u8 af9013_i2c_addr[2]; + bool usb_ts_if_configured[2]; /* for demod callback override */ int (*set_frontend[2]) (struct dvb_frontend *fe); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index d2e80537b2f7..3fd6cc0d6340 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -203,6 +203,8 @@ struct dvb_usb_adapter_properties { * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for * receive * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message + * @probe: like probe on driver model + * @disconnect: like disconnect on driver model * @identify_state: called to determine the firmware state (cold or warm) and * return possible firmware file name to be loaded * @firmware: name of the firmware file to be loaded @@ -239,6 +241,8 @@ struct dvb_usb_device_properties { u8 generic_bulk_ctrl_endpoint_response; unsigned int generic_bulk_ctrl_delay; + int (*probe)(struct dvb_usb_device *); + void (*disconnect)(struct dvb_usb_device *); #define WARM 0 #define COLD 1 int (*identify_state) (struct dvb_usb_device *, const char **); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 2bf3bd81280a..afdcdbf005e9 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -854,8 +854,6 @@ static int dvb_usbv2_exit(struct dvb_usb_device *d) dvb_usbv2_remote_exit(d); dvb_usbv2_adapter_exit(d); dvb_usbv2_i2c_exit(d); - kfree(d->priv); - kfree(d); return 0; } @@ -934,7 +932,7 @@ int dvb_usbv2_probe(struct usb_interface *intf, if (intf->cur_altsetting->desc.bInterfaceNumber != d->props->bInterfaceNumber) { ret = -ENODEV; - goto err_free_all; + goto err_kfree_d; } mutex_init(&d->usb_mutex); @@ -946,10 +944,16 @@ int dvb_usbv2_probe(struct usb_interface *intf, dev_err(&d->udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); ret = -ENOMEM; - goto err_free_all; + goto err_kfree_d; } } + if (d->props->probe) { + ret = d->props->probe(d); + if (ret) + goto err_kfree_priv; + } + if (d->props->identify_state) { const char *name = NULL; ret = d->props->identify_state(d, &name); @@ -1001,6 +1005,12 @@ exit: return 0; err_free_all: dvb_usbv2_exit(d); + if (d->props->disconnect) + d->props->disconnect(d); +err_kfree_priv: + kfree(d->priv); +err_kfree_d: + kfree(d); err: dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret); return ret; @@ -1021,6 +1031,12 @@ void dvb_usbv2_disconnect(struct usb_interface *intf) dvb_usbv2_exit(d); + if (d->props->disconnect) + d->props->disconnect(d); + + kfree(d->priv); + kfree(d); + pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n", KBUILD_MODNAME, drvname, devname); kfree(devname); diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 2abd15c6df81..387a074ea6ec 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -1243,82 +1243,6 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) return 0; } -static int cxusb_mygica_t230c_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dvb_usb_device *d = adap->dev; - struct cxusb_state *st = d->priv; - struct i2c_adapter *adapter; - struct i2c_client *client_demod; - struct i2c_client *client_tuner; - struct i2c_board_info info; - struct si2168_config si2168_config; - struct si2157_config si2157_config; - - /* Select required USB configuration */ - if (usb_set_interface(d->udev, 0, 0) < 0) - err("set interface failed"); - - /* Unblock all USB pipes */ - usb_clear_halt(d->udev, - usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); - usb_clear_halt(d->udev, - usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); - usb_clear_halt(d->udev, - usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); - - /* attach frontend */ - memset(&si2168_config, 0, sizeof(si2168_config)); - si2168_config.i2c_adapter = &adapter; - si2168_config.fe = &adap->fe_adap[0].fe; - si2168_config.ts_mode = SI2168_TS_PARALLEL; - si2168_config.ts_clock_inv = 1; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2168", I2C_NAME_SIZE); - info.addr = 0x64; - info.platform_data = &si2168_config; - request_module(info.type); - client_demod = i2c_new_device(&d->i2c_adap, &info); - if (client_demod == NULL || client_demod->dev.driver == NULL) - return -ENODEV; - - if (!try_module_get(client_demod->dev.driver->owner)) { - i2c_unregister_device(client_demod); - return -ENODEV; - } - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = adap->fe_adap[0].fe; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2141", I2C_NAME_SIZE); - info.addr = 0x60; - info.platform_data = &si2157_config; - request_module("si2157"); - client_tuner = i2c_new_device(adapter, &info); - if (client_tuner == NULL || client_tuner->dev.driver == NULL) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - return -ENODEV; - } - if (!try_module_get(client_tuner->dev.driver->owner)) { - i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - return -ENODEV; - } - - st->i2c_client_demod = client_demod; - st->i2c_client_tuner = client_tuner; - - /* hook fe: need to resync the slave fifo when signal locks. */ - mutex_init(&st->stream_mutex); - st->last_lock = 0; - st->fe_read_status = adap->fe_adap[0].fe->ops.read_status; - adap->fe_adap[0].fe->ops.read_status = cxusb_read_status; - - return 0; -} - /* * DViCO has shipped two devices with the same USB ID, but only one of them * needs a firmware download. Check the device class details to see if they @@ -1401,7 +1325,6 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties; static struct dvb_usb_device_properties cxusb_d680_dmb_properties; static struct dvb_usb_device_properties cxusb_mygica_d689_properties; static struct dvb_usb_device_properties cxusb_mygica_t230_properties; -static struct dvb_usb_device_properties cxusb_mygica_t230c_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -1434,8 +1357,6 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230c_properties, - THIS_MODULE, NULL, adapter_nr) || 0) return 0; @@ -1487,7 +1408,6 @@ enum cxusb_table_index { CONEXANT_D680_DMB, MYGICA_D689, MYGICA_T230, - MYGICA_T230C, NR__cxusb_table_index }; @@ -1555,9 +1475,6 @@ static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = { [MYGICA_T230] = { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) }, - [MYGICA_T230C] = { - USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230+1) - }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -2143,7 +2060,7 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { .rc.core = { .rc_interval = 100, - .rc_codes = RC_MAP_D680_DMB, + .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, .module_name = KBUILD_MODNAME, .rc_query = cxusb_d680_dmb_rc_query, .allowed_protos = RC_PROTO_BIT_UNKNOWN, @@ -2252,7 +2169,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { .rc.core = { .rc_interval = 100, - .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, + .rc_codes = RC_MAP_D680_DMB, .module_name = KBUILD_MODNAME, .rc_query = cxusb_d680_dmb_rc_query, .allowed_protos = RC_PROTO_BIT_UNKNOWN, @@ -2268,60 +2185,6 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { } }; -static struct dvb_usb_device_properties cxusb_mygica_t230c_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .num_frontends = 1, - .fe = {{ - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_mygica_t230c_frontend_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - } }, - }, - }, - - .power_ctrl = cxusb_d680_dmb_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc.core = { - .rc_interval = 100, - .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, - .module_name = KBUILD_MODNAME, - .rc_query = cxusb_d680_dmb_rc_query, - .allowed_protos = RC_PROTO_BIT_UNKNOWN, - }, - - .num_device_descs = 1, - .devices = { - { - "Mygica T230C DVB-T/T2/C", - { NULL }, - { &cxusb_table[MYGICA_T230C], NULL }, - }, - } -}; - static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 3d99e141d566..c53a969bc6be 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -3412,7 +3412,7 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap) static struct s5h1411_config pinnacle_801e_config = { .output_mode = S5H1411_PARALLEL_OUTPUT, .gpio = S5H1411_GPIO_OFF, - .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, + .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK, .qam_if = S5H1411_IF_44000, .vsb_if = S5H1411_IF_44000, .inversion = S5H1411_INVERSION_OFF, diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 4628d73f46f2..8e799ae1df69 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -1,25 +1,25 @@ -/* - * Empiatech em28x1 audio extension - * - * Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com> - * - * Copyright (C) 2007-2016 Mauro Carvalho Chehab - * - Port to work with the in-kernel driver - * - Cleanups, fixes, alsa-controls, etc. - * - * This driver is based on my previous au600 usb pstn audio driver - * and inherits all the copyrights - * - * 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. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Empiatech em28x1 audio extension +// +// Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com> +// +// Copyright (C) 2007-2016 Mauro Carvalho Chehab +// - Port to work with the in-kernel driver +// - Cleanups, fixes, alsa-controls, etc. +// +// This driver is based on my previous au600 usb pstn audio driver +// and inherits all the copyrights +// +// 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" @@ -103,7 +103,7 @@ static void em28xx_audio_isocirq(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - dprintk("urb completition error %d.\n", urb->status); + dprintk("urb completion error %d.\n", urb->status); break; } @@ -165,12 +165,11 @@ static void em28xx_audio_isocirq(struct urb *urb) dev_err(&dev->intf->dev, "resubmit of audio urb failed (error=%i)\n", status); - return; } static int em28xx_init_audio_isoc(struct em28xx *dev) { - int i, errCode; + int i, err; dprintk("Starting isoc transfers\n"); @@ -179,16 +178,15 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, dev->adev.urb[i]->transfer_buffer_length); - errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); - if (errCode) { + err = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); + if (err) { dev_err(&dev->intf->dev, "submit of audio urb failed (error=%i)\n", - errCode); + err); em28xx_deinit_isoc_audio(dev); atomic_set(&dev->adev.stream_started, 0); - return errCode; + return err; } - } return 0; @@ -268,14 +266,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) if (nonblock) { if (!mutex_trylock(&dev->lock)) return -EAGAIN; - } else + } else { mutex_lock(&dev->lock); + } runtime->hw = snd_em28xx_hw_capture; if (dev->adev.users == 0) { - if (dev->alt == 0 || dev->is_audio_only) { - struct usb_device *udev = interface_to_usbdev(dev->intf); + if (!dev->alt || dev->is_audio_only) { + struct usb_device *udev; + + udev = interface_to_usbdev(dev->intf); if (dev->is_audio_only) /* audio is on a separate interface */ @@ -367,9 +368,11 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; #if 0 - /* TODO: set up em28xx audio chip to deliver the correct audio format, - current default is 48000hz multiplexed => 96000hz mono - which shouldn't matter since analogue TV only supports mono */ + /* + * TODO: set up em28xx audio chip to deliver the correct audio format, + * current default is 48000hz multiplexed => 96000hz mono + * which shouldn't matter since analogue TV only supports mono + */ unsigned int channels, rate, format; format = params_format(hw_params); @@ -513,8 +516,9 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol, if (nonblock) { if (!mutex_trylock(&dev->lock)) return -EAGAIN; - } else + } else { mutex_lock(&dev->lock); + } rc = em28xx_read_ac97(dev, kcontrol->private_value); if (rc < 0) goto err; @@ -551,8 +555,9 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol, if (nonblock) { if (!mutex_trylock(&dev->lock)) return -EAGAIN; - } else + } else { mutex_lock(&dev->lock); + } val = em28xx_read_ac97(dev, kcontrol->private_value); mutex_unlock(&dev->lock); if (val < 0) @@ -586,8 +591,9 @@ static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol, if (nonblock) { if (!mutex_trylock(&dev->lock)) return -EAGAIN; - } else + } else { mutex_lock(&dev->lock); + } rc = em28xx_read_ac97(dev, kcontrol->private_value); if (rc < 0) goto err; @@ -627,8 +633,9 @@ static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol, if (nonblock) { if (!mutex_trylock(&dev->lock)) return -EAGAIN; - } else + } else { mutex_lock(&dev->lock); + } val = em28xx_read_ac97(dev, kcontrol->private_value); mutex_unlock(&dev->lock); if (val < 0) @@ -762,7 +769,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) if (intf->num_altsetting <= alt) { dev_err(&dev->intf->dev, "alt %d doesn't exist on interface %d\n", - dev->ifnum, alt); + dev->ifnum, alt); return -ENODEV; } @@ -836,9 +843,8 @@ static int em28xx_audio_urb_init(struct em28xx *dev) dev->adev.transfer_buffer = kcalloc(num_urb, sizeof(*dev->adev.transfer_buffer), GFP_ATOMIC); - if (!dev->adev.transfer_buffer) { + if (!dev->adev.transfer_buffer) return -ENOMEM; - } dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_ATOMIC); if (!dev->adev.urb) { @@ -899,9 +905,11 @@ static int em28xx_audio_init(struct em28xx *dev) int err; if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) { - /* This device does not support the extension (in this case - the device is expecting the snd-usb-audio module or - doesn't have analog audio support at all) */ + /* + * This device does not support the extension (in this case + * the device is expecting the snd-usb-audio module or + * doesn't have analog audio support at all) + */ return 0; } @@ -977,13 +985,15 @@ card_free: static int em28xx_audio_fini(struct em28xx *dev) { - if (dev == NULL) + if (!dev) return 0; if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) { - /* This device does not support the extension (in this case - the device is expecting the snd-usb-audio module or - doesn't have analog audio support at all) */ + /* + * This device does not support the extension (in this case + * the device is expecting the snd-usb-audio module or + * doesn't have analog audio support at all) + */ return 0; } @@ -1005,7 +1015,7 @@ static int em28xx_audio_fini(struct em28xx *dev) static int em28xx_audio_suspend(struct em28xx *dev) { - if (dev == NULL) + if (!dev) return 0; if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) @@ -1019,7 +1029,7 @@ static int em28xx_audio_suspend(struct em28xx *dev) static int em28xx_audio_resume(struct em28xx *dev) { - if (dev == NULL) + if (!dev) return 0; if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) @@ -1050,7 +1060,7 @@ static void __exit em28xx_alsa_unregister(void) em28xx_unregister_extension(&audio_ops); } -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>"); MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_DESCRIPTION(DRIVER_DESC " - audio interface"); diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index ae87dd3e671f..3c2694a16ed1 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -1,23 +1,19 @@ -/* - em28xx-camera.c - driver for Empia EM25xx/27xx/28xx USB video capture devices - - Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> - Copyright (C) 2013 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ +// SPDX-License-Identifier: GPL-2.0+ +// +// em28xx-camera.c - driver for Empia EM25xx/27xx/28xx USB video capture devices +// +// Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> +// Copyright (C) 2013 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" @@ -49,7 +45,7 @@ static int em28xx_initialize_mt9m111(struct em28xx *dev) { 0x0d, 0x00, 0x01, }, /* reset and use defaults */ { 0x0d, 0x00, 0x00, }, { 0x0a, 0x00, 0x21, }, - { 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */ + { 0x21, 0x04, 0x00, }, /* full readout spd, no row/col skip */ }; for (i = 0; i < ARRAY_SIZE(regs); i++) @@ -157,7 +153,8 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) break; default: dev_info(&dev->intf->dev, - "unknown Micron sensor detected: 0x%04x\n", id); + "unknown Micron sensor detected: 0x%04x\n", + id); return 0; } @@ -186,8 +183,10 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; dev->em28xx_sensor = EM28XX_NOSENSOR; - /* NOTE: these devices have the register auto incrementation disabled - * by default, so we have to use single byte reads ! */ + /* + * NOTE: these devices have the register auto incrementation disabled + * by default, so we have to use single byte reads ! + */ for (i = 0; omnivision_sensor_addrs[i] != I2C_CLIENT_END; i++) { client->addr = omnivision_sensor_addrs[i]; /* Read manufacturer ID from registers 0x1c-0x1d (BE) */ @@ -397,7 +396,7 @@ int em28xx_init_camera(struct em28xx *dev) subdev = v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, &ov2640_info, NULL); - if (subdev == NULL) + if (!subdev) return -ENODEV; format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 34e16f6ab4ac..6e0e67d23876 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -1,27 +1,23 @@ -/* - em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB - video capture devices - - Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> - Markus Rechberger <mrechberger@gmail.com> - Mauro Carvalho Chehab <mchehab@infradead.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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB +// video capture devices +// +// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> +// Markus Rechberger <mrechberger@gmail.com> +// Mauro Carvalho Chehab <mchehab@infradead.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" @@ -40,7 +36,6 @@ #include <media/v4l2-common.h> #include <sound/ac97_codec.h> - #define DRIVER_NAME "em28xx" static int tuner = -1; @@ -81,26 +76,26 @@ static void em28xx_pre_card_setup(struct em28xx *dev); */ /* Reset for the most [analog] boards */ -static struct em28xx_reg_seq default_analog[] = { +static const struct em28xx_reg_seq default_analog[] = { {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, { -1, -1, -1, -1}, }; /* Reset for the most [digital] boards */ -static struct em28xx_reg_seq default_digital[] = { +static const struct em28xx_reg_seq default_digital[] = { {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, { -1, -1, -1, -1}, }; /* Board Hauppauge WinTV HVR 900 analog */ -static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { +static const struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { {EM2820_R08_GPIO_CTRL, 0x2d, ~EM_GPIO_4, 10}, { 0x05, 0xff, 0x10, 10}, { -1, -1, -1, -1}, }; /* Board Hauppauge WinTV HVR 900 digital */ -static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { +static const struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, {EM2880_R04_GPO, 0x04, 0x0f, 10}, {EM2880_R04_GPO, 0x0c, 0x0f, 10}, @@ -108,25 +103,20 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { }; /* Board Hauppauge WinTV HVR 900 (R2) digital */ -static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = { +static const struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = { {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, {EM2880_R04_GPO, 0x0c, 0x0f, 10}, { -1, -1, -1, -1}, }; /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ -static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { +static const struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { {EM2820_R08_GPIO_CTRL, 0x69, ~EM_GPIO_4, 10}, { -1, -1, -1, -1}, }; -/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ - -/* Board - EM2870 Kworld 355u - Analog - No input analog */ - /* Board - EM2882 Kworld 315U digital */ -static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { +static const struct em28xx_reg_seq em2882_kworld_315u_digital[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, {EM2880_R04_GPO, 0x04, 0xff, 10}, @@ -135,7 +125,7 @@ static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { +static const struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { {EM2880_R04_GPO, 0x08, 0xff, 10}, {EM2880_R04_GPO, 0x0c, 0xff, 10}, {EM2880_R04_GPO, 0x08, 0xff, 10}, @@ -143,30 +133,31 @@ static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq kworld_330u_analog[] = { +static const struct em28xx_reg_seq kworld_330u_analog[] = { {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, {EM2880_R04_GPO, 0x00, 0xff, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq kworld_330u_digital[] = { +static const struct em28xx_reg_seq kworld_330u_digital[] = { {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, {EM2880_R04_GPO, 0x08, 0xff, 10}, { -1, -1, -1, -1}, }; -/* Evga inDtube - GPIO0 - Enable digital power (s5h1409) - low to enable - GPIO1 - Enable analog power (tvp5150/emp202) - low to enable - GPIO4 - xc3028 reset - GOP3 - s5h1409 reset +/* + * Evga inDtube + * GPIO0 - Enable digital power (s5h1409) - low to enable + * GPIO1 - Enable analog power (tvp5150/emp202) - low to enable + * GPIO4 - xc3028 reset + * GOP3 - s5h1409 reset */ -static struct em28xx_reg_seq evga_indtube_analog[] = { +static const struct em28xx_reg_seq evga_indtube_analog[] = { {EM2820_R08_GPIO_CTRL, 0x79, 0xff, 60}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq evga_indtube_digital[] = { +static const struct em28xx_reg_seq evga_indtube_digital[] = { {EM2820_R08_GPIO_CTRL, 0x7a, 0xff, 1}, {EM2880_R04_GPO, 0x04, 0xff, 10}, {EM2880_R04_GPO, 0x0c, 0xff, 1}, @@ -184,12 +175,12 @@ static struct em28xx_reg_seq evga_indtube_digital[] = { * EM_GPIO_6 - currently unknown * EM_GPIO_7 - currently unknown */ -static struct em28xx_reg_seq kworld_a340_digital[] = { +static const struct em28xx_reg_seq kworld_a340_digital[] = { {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq kworld_ub435q_v3_digital[] = { +static const struct em28xx_reg_seq kworld_ub435q_v3_digital[] = { {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xbe, 0xff, 100}, @@ -198,45 +189,49 @@ static struct em28xx_reg_seq kworld_ub435q_v3_digital[] = { }; /* Pinnacle Hybrid Pro eb1a:2881 */ -static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { +static const struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { {EM2820_R08_GPIO_CTRL, 0xfd, ~EM_GPIO_4, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { +static const struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */ {EM2880_R04_GPO, 0x0c, 0xff, 1}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { +static const struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, {EM2880_R04_GPO, 0x00, 0xff, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { +static const struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, {EM2880_R04_GPO, 0x08, 0xff, 10}, { -1, -1, -1, -1}, }; -/* PCTV HD Mini (80e) GPIOs - 0-5: not used - 6: demod reset, active low - 7: LED on, active high */ -static struct em28xx_reg_seq em2874_pctv_80e_digital[] = { +/* + * PCTV HD Mini (80e) GPIOs + * 0-5: not used + * 6: demod reset, active low + * 7: LED on, active high + */ +static const struct em28xx_reg_seq em2874_pctv_80e_digital[] = { {EM28XX_R06_I2C_CLK, 0x45, 0xff, 10}, /*400 KHz*/ {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 100},/*Demod reset*/ {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 10}, { -1, -1, -1, -1}, }; -/* eb1a:2868 Reddo DVB-C USB TV Box - GPIO4 - CU1216L NIM - Other GPIOs seems to be don't care. */ -static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { +/* + * eb1a:2868 Reddo DVB-C USB TV Box + * GPIO4 - CU1216L NIM + * Other GPIOs seems to be don't care. + */ +static const struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, {EM2820_R08_GPIO_CTRL, 0xde, 0xff, 10}, {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, @@ -248,7 +243,7 @@ static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { }; /* Callback for the most boards */ -static struct em28xx_reg_seq default_tuner_gpio[] = { +static const struct em28xx_reg_seq default_tuner_gpio[] = { {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, {EM2820_R08_GPIO_CTRL, 0, EM_GPIO_4, 10}, {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, @@ -256,69 +251,70 @@ static struct em28xx_reg_seq default_tuner_gpio[] = { }; /* Mute/unmute */ -static struct em28xx_reg_seq compro_unmute_tv_gpio[] = { +static const struct em28xx_reg_seq compro_unmute_tv_gpio[] = { {EM2820_R08_GPIO_CTRL, 5, 7, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq compro_unmute_svid_gpio[] = { +static const struct em28xx_reg_seq compro_unmute_svid_gpio[] = { {EM2820_R08_GPIO_CTRL, 4, 7, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq compro_mute_gpio[] = { +static const struct em28xx_reg_seq compro_mute_gpio[] = { {EM2820_R08_GPIO_CTRL, 6, 7, 10}, { -1, -1, -1, -1}, }; /* Terratec AV350 */ -static struct em28xx_reg_seq terratec_av350_mute_gpio[] = { +static const struct em28xx_reg_seq terratec_av350_mute_gpio[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0x7f, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { +static const struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq silvercrest_reg_seq[] = { +static const struct em28xx_reg_seq silvercrest_reg_seq[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, {EM2820_R08_GPIO_CTRL, 0x01, 0xf7, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq vc211a_enable[] = { +static const struct em28xx_reg_seq vc211a_enable[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0x07, 10}, {EM2820_R08_GPIO_CTRL, 0xff, 0x0f, 10}, {EM2820_R08_GPIO_CTRL, 0xff, 0x0b, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq dikom_dk300_digital[] = { +static const struct em28xx_reg_seq dikom_dk300_digital[] = { {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, {EM2880_R04_GPO, 0x08, 0xff, 10}, { -1, -1, -1, -1}, }; /* Reset for the most [digital] boards */ -static struct em28xx_reg_seq leadership_digital[] = { +static const struct em28xx_reg_seq leadership_digital[] = { {EM2874_R80_GPIO_P0_CTRL, 0x70, 0xff, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq leadership_reset[] = { +static const struct em28xx_reg_seq leadership_reset[] = { {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xb0, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, { -1, -1, -1, -1}, }; -/* 2013:024f PCTV nanoStick T2 290e +/* + * 2013:024f PCTV nanoStick T2 290e * GPIO_6 - demod reset * GPIO_7 - LED */ -static struct em28xx_reg_seq pctv_290e[] = { +static const struct em28xx_reg_seq pctv_290e[] = { {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 80}, {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 80}, /* GPIO_6 = 1 */ {EM2874_R80_GPIO_P0_CTRL, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */ @@ -326,7 +322,7 @@ static struct em28xx_reg_seq pctv_290e[] = { }; #if 0 -static struct em28xx_reg_seq terratec_h5_gpio[] = { +static const struct em28xx_reg_seq terratec_h5_gpio[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50}, @@ -334,7 +330,7 @@ static struct em28xx_reg_seq terratec_h5_gpio[] = { { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq terratec_h5_digital[] = { +static const struct em28xx_reg_seq terratec_h5_digital[] = { {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, @@ -342,7 +338,8 @@ static struct em28xx_reg_seq terratec_h5_digital[] = { }; #endif -/* 2013:024f PCTV DVB-S2 Stick 460e +/* + * 2013:024f PCTV DVB-S2 Stick 460e * GPIO_0 - POWER_ON * GPIO_1 - BOOST * GPIO_2 - VUV_LNB (red LED) @@ -352,7 +349,7 @@ static struct em28xx_reg_seq terratec_h5_digital[] = { * GPIO_6 - RESET_DEM * GPIO_7 - LED (green LED) */ -static struct em28xx_reg_seq pctv_460e[] = { +static const struct em28xx_reg_seq pctv_460e[] = { {EM2874_R80_GPIO_P0_CTRL, 0x01, 0xff, 50}, { 0x0d, 0xff, 0xff, 50}, {EM2874_R80_GPIO_P0_CTRL, 0x41, 0xff, 50}, /* GPIO_6=1 */ @@ -361,7 +358,7 @@ static struct em28xx_reg_seq pctv_460e[] = { { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { +static const struct em28xx_reg_seq c3tech_digital_duo_digital[] = { {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 10}, /* xc5000 reset */ {EM2874_R80_GPIO_P0_CTRL, 0xf9, 0xff, 35}, @@ -384,7 +381,7 @@ static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { * GPIO 6 = #RESET_DEM * GPIO 7 = P07_LED (green LED) */ -static struct em28xx_reg_seq pctv_461e[] = { +static const struct em28xx_reg_seq pctv_461e[] = { {EM2874_R80_GPIO_P0_CTRL, 0x7f, 0xff, 0}, {0x0d, 0xff, 0xff, 0}, {EM2874_R80_GPIO_P0_CTRL, 0x3f, 0xff, 100}, /* reset demod */ @@ -396,7 +393,7 @@ static struct em28xx_reg_seq pctv_461e[] = { }; #if 0 -static struct em28xx_reg_seq hauppauge_930c_gpio[] = { +static const struct em28xx_reg_seq hauppauge_930c_gpio[] = { {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10}, /* xc5000 reset */ {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, @@ -404,7 +401,7 @@ static struct em28xx_reg_seq hauppauge_930c_gpio[] = { { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq hauppauge_930c_digital[] = { +static const struct em28xx_reg_seq hauppauge_930c_digital[] = { {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, @@ -412,38 +409,41 @@ static struct em28xx_reg_seq hauppauge_930c_digital[] = { }; #endif -/* 1b80:e425 MaxMedia UB425-TC +/* + * 1b80:e425 MaxMedia UB425-TC * 1b80:e1cc Delock 61959 * GPIO_6 - demod reset, 0=active * GPIO_7 - LED, 0=active */ -static struct em28xx_reg_seq maxmedia_ub425_tc[] = { +static const struct em28xx_reg_seq maxmedia_ub425_tc[] = { {EM2874_R80_GPIO_P0_CTRL, 0x83, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */ {EM2874_R80_GPIO_P0_CTRL, 0x43, 0xff, 000}, /* GPIO_7 = 0 */ { -1, -1, -1, -1}, }; -/* 2304:0242 PCTV QuatroStick (510e) +/* + * 2304:0242 PCTV QuatroStick (510e) * GPIO_2: decoder reset, 0=active * GPIO_4: decoder suspend, 0=active * GPIO_6: demod reset, 0=active * GPIO_7: LED, 1=active */ -static struct em28xx_reg_seq pctv_510e[] = { +static const struct em28xx_reg_seq pctv_510e[] = { {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ { -1, -1, -1, -1}, }; -/* 2013:0251 PCTV QuatroStick nano (520e) +/* + * 2013:0251 PCTV QuatroStick nano (520e) * GPIO_2: decoder reset, 0=active * GPIO_4: decoder suspend, 0=active * GPIO_6: demod reset, 0=active * GPIO_7: LED, 1=active */ -static struct em28xx_reg_seq pctv_520e[] = { +static const struct em28xx_reg_seq pctv_520e[] = { {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ @@ -451,7 +451,8 @@ static struct em28xx_reg_seq pctv_520e[] = { { -1, -1, -1, -1}, }; -/* 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam +/* + * 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam * reg 0x80/0x84: * GPIO_0: capturing LED, 0=on, 1=off * GPIO_2: AV mute button, 0=pressed, 1=unpressed @@ -460,13 +461,13 @@ static struct em28xx_reg_seq pctv_520e[] = { * reg 0x81/0x85: * GPIO_7: snapshot button, 0=pressed, 1=unpressed */ -static struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = { +static const struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = { {EM2820_R08_GPIO_CTRL, 0xf7, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xb2, 10}, { -1, -1, -1, -1}, }; -static struct em28xx_reg_seq pctv_292e[] = { +static const struct em28xx_reg_seq pctv_292e[] = { {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, {0x0d, 0xff, 0xff, 950}, {EM2874_R80_GPIO_P0_CTRL, 0xbd, 0xff, 100}, @@ -478,7 +479,7 @@ static struct em28xx_reg_seq pctv_292e[] = { {-1, -1, -1, -1}, }; -static struct em28xx_reg_seq terratec_t2_stick_hd[] = { +static const struct em28xx_reg_seq terratec_t2_stick_hd[] = { {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, {0x0d, 0xff, 0xff, 600}, {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 10}, @@ -492,7 +493,7 @@ static struct em28xx_reg_seq terratec_t2_stick_hd[] = { {-1, -1, -1, -1}, }; -static struct em28xx_reg_seq plex_px_bcud[] = { +static const struct em28xx_reg_seq plex_px_bcud[] = { {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, {0x0d, 0xff, 0xff, 0}, {EM2874_R50_IR_CONFIG, 0x01, 0xff, 0}, @@ -507,8 +508,10 @@ static struct em28xx_reg_seq plex_px_bcud[] = { }; /* - * 2040:0265 Hauppauge WinTV-dualHD DVB - * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM + * 2040:0265 Hauppauge WinTV-dualHD DVB Isoc + * 2040:8265 Hauppauge WinTV-dualHD DVB Bulk + * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM Isoc + * 2040:826d Hauppauge WinTV-dualHD ATSC/QAM Bulk * reg 0x80/0x84: * GPIO_0: Yellow LED tuner 1, 0=on, 1=off * GPIO_1: Green LED tuner 1, 0=on, 1=off @@ -517,7 +520,7 @@ static struct em28xx_reg_seq plex_px_bcud[] = { * GPIO_5: Reset #2, 0=active * GPIO_6: Reset #1, 0=active */ -static struct em28xx_reg_seq hauppauge_dualhd_dvb[] = { +static const struct em28xx_reg_seq hauppauge_dualhd_dvb[] = { {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, {0x0d, 0xff, 0xff, 200}, {0x50, 0x04, 0xff, 300}, @@ -534,7 +537,7 @@ static struct em28xx_reg_seq hauppauge_dualhd_dvb[] = { /* * Button definitions */ -static struct em28xx_button std_snapshot_button[] = { +static const struct em28xx_button std_snapshot_button[] = { { .role = EM28XX_BUTTON_SNAPSHOT, .reg_r = EM28XX_R0C_USBSUSP, @@ -545,7 +548,7 @@ static struct em28xx_button std_snapshot_button[] = { {-1, 0, 0, 0, 0}, }; -static struct em28xx_button speedlink_vad_laplace_buttons[] = { +static const struct em28xx_button speedlink_vad_laplace_buttons[] = { { .role = EM28XX_BUTTON_SNAPSHOT, .reg_r = EM2874_R85_GPIO_P1_STATE, @@ -629,7 +632,7 @@ static struct em28xx_led hauppauge_dualhd_leds[] = { /* * Board definitions */ -struct em28xx_board em28xx_boards[] = { +const struct em28xx_board em28xx_boards[] = { [EM2750_BOARD_UNKNOWN] = { .name = "EM2710/EM2750/EM2751 webcam grabber", .xclk = EM28XX_XCLK_FREQUENCY_20MHZ, @@ -1436,9 +1439,11 @@ struct em28xx_board em28xx_boards[] = { .gpio = default_analog, } }, }, - /* maybe there's a reason behind it why Terratec sells the Hybrid XS - as Prodigy XS with a different PID, let's keep it separated for now - maybe we'll need it lateron */ + /* + * maybe there's a reason behind it why Terratec sells the Hybrid XS + * as Prodigy XS with a different PID, let's keep it separated for now + * maybe we'll need it later on + */ [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { .name = "Terratec Prodigy XS", .tuner_type = TUNER_XC2028, @@ -1782,8 +1787,9 @@ struct em28xx_board em28xx_boards[] = { .ir_codes = RC_MAP_KWORLD_315U, .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, - /* Analog mode - still not ready */ - /*.input = { { +#if 0 + /* FIXME: Analog mode - still not ready */ + .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = SAA7115_COMPOSITE2, .amux = EM28XX_AMUX_VIDEO, @@ -1801,7 +1807,8 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, .gpio = em2882_kworld_315u_analog1, .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, - } }, */ + } }, +#endif }, [EM2880_BOARD_EMPIRE_DUAL_TV] = { .name = "Empire dual TV", @@ -2162,17 +2169,21 @@ struct em28xx_board em28xx_boards[] = { .gpio = evga_indtube_analog, } }, }, - /* eb1a:2868 Empia EM2870 + Philips CU1216L NIM (Philips TDA10023 + - Infineon TUA6034) */ + /* + * eb1a:2868 Empia EM2870 + Philips CU1216L NIM + * (Philips TDA10023 + Infineon TUA6034) + */ [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { .name = "Reddo DVB-C USB TV Box", .tuner_type = TUNER_ABSENT, .tuner_gpio = reddo_dvb_c_usb_box, .has_dvb = 1, }, - /* 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold + /* + * 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold * initially as the KWorld PlusTV 340U, then as the UB435-Q. - * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 */ + * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 + */ [EM2870_BOARD_KWORLD_A340] = { .name = "KWorld PlusTV 340U or UB435-Q (ATSC)", .tuner_type = TUNER_ABSENT, /* Digital-only TDA18271HD */ @@ -2180,30 +2191,38 @@ struct em28xx_board em28xx_boards[] = { .dvb_gpio = kworld_a340_digital, .tuner_gpio = default_tuner_gpio, }, - /* 2013:024f PCTV nanoStick T2 290e. - * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */ + /* + * 2013:024f PCTV nanoStick T2 290e. + * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 + */ [EM28174_BOARD_PCTV_290E] = { .name = "PCTV nanoStick T2 290e", .def_i2c_bus = 1, - .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_100_KHZ, .tuner_type = TUNER_ABSENT, .tuner_gpio = pctv_290e, .has_dvb = 1, .ir_codes = RC_MAP_PINNACLE_PCTV_HD, }, - /* 2013:024f PCTV DVB-S2 Stick 460e - * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293 */ + /* + * 2013:024f PCTV DVB-S2 Stick 460e + * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293 + */ [EM28174_BOARD_PCTV_460E] = { .def_i2c_bus = 1, - .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, .name = "PCTV DVB-S2 Stick (460e)", .tuner_type = TUNER_ABSENT, .tuner_gpio = pctv_460e, .has_dvb = 1, .ir_codes = RC_MAP_PINNACLE_PCTV_HD, }, - /* eb1a:5006 Honestech VIDBOX NW03 - * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner */ + /* + * eb1a:5006 Honestech VIDBOX NW03 + * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner + */ [EM2860_BOARD_HT_VIDBOX_NW03] = { .name = "Honestech Vidbox NW03", .tuner_type = TUNER_ABSENT, @@ -2214,12 +2233,14 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, /* S-VIDEO needs confirming */ + .vmux = SAA7115_SVIDEO3, /* S-VIDEO needs check */ .amux = EM28XX_AMUX_LINE_IN, } }, }, - /* 1b80:e425 MaxMedia UB425-TC - * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 */ + /* + * 1b80:e425 MaxMedia UB425-TC + * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 + */ [EM2874_BOARD_MAXMEDIA_UB425_TC] = { .name = "MaxMedia UB425-TC", .tuner_type = TUNER_ABSENT, @@ -2230,8 +2251,10 @@ struct em28xx_board em28xx_boards[] = { .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, - /* 2304:0242 PCTV QuatroStick (510e) - * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ + /* + * 2304:0242 PCTV QuatroStick (510e) + * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 + */ [EM2884_BOARD_PCTV_510E] = { .name = "PCTV QuatroStick (510e)", .tuner_type = TUNER_ABSENT, @@ -2242,8 +2265,10 @@ struct em28xx_board em28xx_boards[] = { .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, - /* 2013:0251 PCTV QuatroStick nano (520e) - * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ + /* + * 2013:0251 PCTV QuatroStick nano (520e) + * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 + */ [EM2884_BOARD_PCTV_520E] = { .name = "PCTV QuatroStick nano (520e)", .tuner_type = TUNER_ABSENT, @@ -2263,9 +2288,11 @@ struct em28xx_board em28xx_boards[] = { .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, - /* 1b80:e1cc Delock 61959 + /* + * 1b80:e1cc Delock 61959 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 - * mostly the same as MaxMedia UB-425-TC but different remote */ + * mostly the same as MaxMedia UB-425-TC but different remote + */ [EM2874_BOARD_DELOCK_61959] = { .name = "Delock 61959", .tuner_type = TUNER_ABSENT, @@ -2311,8 +2338,10 @@ struct em28xx_board em28xx_boards[] = { .ir_codes = RC_MAP_PINNACLE_PCTV_HD, .leds = pctv_80e_leds, }, - /* 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam - * Empia EM2765 + OmniVision OV2640 */ + /* + * 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam + * Empia EM2765 + OmniVision OV2640 + */ [EM2765_BOARD_SPEEDLINK_VAD_LAPLACE] = { .name = "SpeedLink Vicious And Devine Laplace webcam", .xclk = EM28XX_XCLK_FREQUENCY_24MHZ, @@ -2329,23 +2358,29 @@ struct em28xx_board em28xx_boards[] = { .buttons = speedlink_vad_laplace_buttons, .leds = speedlink_vad_laplace_leds, }, - /* 2013:0258 PCTV DVB-S2 Stick (461e) - * Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293 */ + /* + * 2013:0258 PCTV DVB-S2 Stick (461e) + * Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293 + */ [EM28178_BOARD_PCTV_461E] = { .def_i2c_bus = 1, - .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, .name = "PCTV DVB-S2 Stick (461e)", .tuner_type = TUNER_ABSENT, .tuner_gpio = pctv_461e, .has_dvb = 1, .ir_codes = RC_MAP_PINNACLE_PCTV_HD, }, - /* 2013:025f PCTV tripleStick (292e). - * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157 */ + /* + * 2013:025f PCTV tripleStick (292e). + * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157 + */ [EM28178_BOARD_PCTV_292E] = { .name = "PCTV tripleStick (292e)", .def_i2c_bus = 1, - .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, .tuner_type = TUNER_ABSENT, .tuner_gpio = pctv_292e, .has_dvb = 1, @@ -2365,12 +2400,15 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, - /* eb1a:8179 Terratec Cinergy T2 Stick HD. - * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2146 */ + /* + * eb1a:8179 Terratec Cinergy T2 Stick HD. + * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2146 + */ [EM28178_BOARD_TERRATEC_T2_STICK_HD] = { .name = "Terratec Cinergy T2 Stick HD", .def_i2c_bus = 1, - .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, .tuner_type = TUNER_ABSENT, .tuner_gpio = terratec_t2_stick_hd, .has_dvb = 1, @@ -2391,7 +2429,8 @@ struct em28xx_board em28xx_boards[] = { .has_dvb = 1, }, /* - * 2040:0265 Hauppauge WinTV-dualHD (DVB version). + * 2040:0265 Hauppauge WinTV-dualHD (DVB version) Isoc. + * 2040:8265 Hauppauge WinTV-dualHD (DVB version) Bulk. * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157 */ [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = { @@ -2402,11 +2441,13 @@ struct em28xx_board em28xx_boards[] = { .tuner_type = TUNER_ABSENT, .tuner_gpio = hauppauge_dualhd_dvb, .has_dvb = 1, + .has_dual_ts = 1, .ir_codes = RC_MAP_HAUPPAUGE, .leds = hauppauge_dualhd_leds, }, /* - * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM). + * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Isoc. + * 2040:826d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Bulk. * Empia EM28274, 2x LG LGDT3306A, 2x Silicon Labs Si2157 */ [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595] = { @@ -2417,6 +2458,7 @@ struct em28xx_board em28xx_boards[] = { .tuner_type = TUNER_ABSENT, .tuner_gpio = hauppauge_dualhd_dvb, .has_dvb = 1, + .has_dual_ts = 1, .ir_codes = RC_MAP_HAUPPAUGE, .leds = hauppauge_dualhd_leds, }, @@ -2485,10 +2527,10 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2870_BOARD_KWORLD_355U }, { USB_DEVICE(0xeb1a, 0xe359), .driver_info = EM2870_BOARD_KWORLD_355U }, - { USB_DEVICE(0x1b80, 0xe302), - .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */ - { USB_DEVICE(0x1b80, 0xe304), - .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kworld DVD Maker 2 */ + { USB_DEVICE(0x1b80, 0xe302), /* Kaiser Baas Video to DVD maker */ + .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x1b80, 0xe304), /* Kworld DVD Maker 2 */ + .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, { USB_DEVICE(0x0ccd, 0x004c), @@ -2547,8 +2589,12 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, { USB_DEVICE(0x2040, 0x0265), .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, + { USB_DEVICE(0x2040, 0x8265), + .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, { USB_DEVICE(0x2040, 0x026d), .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 }, + { USB_DEVICE(0x2040, 0x826d), + .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 }, { USB_DEVICE(0x0438, 0xb002), .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, { USB_DEVICE(0x2001, 0xf112), @@ -2609,7 +2655,13 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM28178_BOARD_PCTV_461E }, { USB_DEVICE(0x2013, 0x025f), .driver_info = EM28178_BOARD_PCTV_292E }, - { USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD */ + { USB_DEVICE(0x2013, 0x0264), /* Hauppauge WinTV-soloHD 292e SE */ + .driver_info = EM28178_BOARD_PCTV_292E }, + { USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD Isoc */ + .driver_info = EM28178_BOARD_PCTV_292E }, + { USB_DEVICE(0x2040, 0x8264), /* Hauppauge OEM Generic WinTV-soloHD Bulk */ + .driver_info = EM28178_BOARD_PCTV_292E }, + { USB_DEVICE(0x2040, 0x8268), /* Hauppauge Retail WinTV-soloHD Bulk */ .driver_info = EM28178_BOARD_PCTV_292E }, { USB_DEVICE(0x0413, 0x6f07), .driver_info = EM2861_BOARD_LEADTEK_VC100 }, @@ -2626,7 +2678,7 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table); /* * EEPROM hash table for devices with generic USB IDs */ -static struct em28xx_hash_table em28xx_eeprom_hash[] = { +static const struct em28xx_hash_table em28xx_eeprom_hash[] = { /* P/N: SA 60002070465 Tuner: TVF7533-MF */ {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, @@ -2639,7 +2691,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = { }; /* I2C devicelist hash table for devices with generic USB IDs */ -static struct em28xx_hash_table em28xx_i2c_hash[] = { +static const struct em28xx_hash_table em28xx_i2c_hash[] = { {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, @@ -2669,26 +2721,46 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) } EXPORT_SYMBOL_GPL(em28xx_tuner_callback); -static inline void em28xx_set_model(struct em28xx *dev) +static inline void em28xx_set_xclk_i2c_speed(struct em28xx *dev) { - dev->board = em28xx_boards[dev->model]; + const struct em28xx_board *board = &em28xx_boards[dev->model]; + u8 xclk = board->xclk, i2c_speed = board->i2c_speed; - /* Those are the default values for the majority of boards - Use those values if not specified otherwise at boards entry + /* + * Those are the default values for the majority of boards + * Use those values if not specified otherwise at boards entry */ - if (!dev->board.xclk) - dev->board.xclk = EM28XX_XCLK_IR_RC5_MODE | - EM28XX_XCLK_FREQUENCY_12MHZ; + if (!xclk) + xclk = EM28XX_XCLK_IR_RC5_MODE | + EM28XX_XCLK_FREQUENCY_12MHZ; + + em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); - if (!dev->board.i2c_speed) - dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | - EM28XX_I2C_FREQ_100_KHZ; + if (!i2c_speed) + i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_100_KHZ; + + dev->i2c_speed = i2c_speed & 0x03; + + if (!dev->board.is_em2800) + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, i2c_speed); + msleep(50); +} + +static inline void em28xx_set_model(struct em28xx *dev) +{ + dev->board = em28xx_boards[dev->model]; + dev->has_msp34xx = dev->board.has_msp34xx; + dev->is_webcam = dev->board.is_webcam; + + em28xx_set_xclk_i2c_speed(dev); /* Should be initialized early, for I2C to work */ dev->def_i2c_bus = dev->board.def_i2c_bus; } -/* Wait until AC97_RESET reports the expected value reliably before proceeding. +/* + * Wait until AC97_RESET reports the expected value reliably before proceeding. * We also check that two unrelated registers accesses don't return the same * value to avoid premature return. * This procedure helps ensuring AC97 register accesses are reliable. @@ -2718,17 +2790,17 @@ static int em28xx_wait_until_ac97_features_equals(struct em28xx *dev, return -ETIMEDOUT; } -/* Since em28xx_pre_card_setup() requires a proper dev->model, +/* + * Since em28xx_pre_card_setup() requires a proper dev->model, * this won't work for boards with generic PCI IDs */ static void em28xx_pre_card_setup(struct em28xx *dev) { - /* Set the initial XCLK and I2C clock values based on the board - definition */ - em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f); - if (!dev->board.is_em2800) - em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); - msleep(50); + /* + * Set the initial XCLK and I2C clock values based on the board + * definition + */ + em28xx_set_xclk_i2c_speed(dev); /* request some modules */ switch (dev->model) { @@ -2739,17 +2811,19 @@ static void em28xx_pre_card_setup(struct em28xx *dev) case EM2861_BOARD_KWORLD_PVRTV_300U: case EM2880_BOARD_KWORLD_DVB_305U: em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x6d); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x7d); - msleep(10); + usleep_range(10000, 11000); break; case EM2870_BOARD_COMPRO_VIDEOMATE: - /* TODO: someone can do some cleanup here... - not everything's needed */ + /* + * TODO: someone can do some cleanup here... + * not everything's needed + */ em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM2880_R04_GPO, 0x01); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); mdelay(70); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc); @@ -2760,8 +2834,10 @@ static void em28xx_pre_card_setup(struct em28xx *dev) mdelay(70); break; case EM2870_BOARD_TERRATEC_XS_MT2060: - /* this device needs some gpio writes to get the DVB-T - demod work */ + /* + * this device needs some gpio writes to get the DVB-T + * demod work + */ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); mdelay(70); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde); @@ -2770,8 +2846,10 @@ static void em28xx_pre_card_setup(struct em28xx *dev) mdelay(70); break; case EM2870_BOARD_PINNACLE_PCTV_DVB: - /* this device needs some gpio writes to get the - DVB-T demod work */ + /* + * this device needs some gpio writes to get the + * DVB-T demod work + */ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); mdelay(70); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde); @@ -2787,13 +2865,13 @@ static void em28xx_pre_card_setup(struct em28xx *dev) case EM2882_BOARD_KWORLD_ATSC_315U: em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM2880_R04_GPO, 0x08); - msleep(10); + usleep_range(10000, 11000); break; case EM2860_BOARD_KAIOMY_TVNPC_U2: @@ -2801,11 +2879,11 @@ static void em28xx_pre_card_setup(struct em28xx *dev) em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); em28xx_write_regs(dev, 0x0d, "\x42", 1); em28xx_write_regs(dev, 0x08, "\xfd", 1); - msleep(10); + usleep_range(10000, 11000); em28xx_write_regs(dev, 0x08, "\xff", 1); - msleep(10); + usleep_range(10000, 11000); em28xx_write_regs(dev, 0x08, "\x7f", 1); - msleep(10); + usleep_range(10000, 11000); em28xx_write_regs(dev, 0x08, "\x6b", 1); break; @@ -2817,7 +2895,7 @@ static void em28xx_pre_card_setup(struct em28xx *dev) em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); msleep(70); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); msleep(70); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); @@ -2825,7 +2903,8 @@ static void em28xx_pre_card_setup(struct em28xx *dev) break; case EM2860_BOARD_TERRATEC_GRABBY: - /* HACK?: Ensure AC97 register reading is reliable before + /* + * HACK?: Ensure AC97 register reading is reliable before * proceeding. In practice, this will wait about 1.6 seconds. */ em28xx_wait_until_ac97_features_equals(dev, 0x6a90); @@ -2843,7 +2922,7 @@ static int em28xx_hint_board(struct em28xx *dev) { int i; - if (dev->board.is_webcam) { + if (dev->is_webcam) { if (dev->em28xx_sensor == EM28XX_MT9V011) { dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; } else if (dev->em28xx_sensor == EM28XX_MT9M001 || @@ -2855,7 +2934,8 @@ static int em28xx_hint_board(struct em28xx *dev) return 0; } - /* HINT method: EEPROM + /* + * HINT method: EEPROM * * This method works only for boards with eeprom. * Uses a hash of all eeprom bytes. The hash should be @@ -2881,7 +2961,8 @@ static int em28xx_hint_board(struct em28xx *dev) } } - /* HINT method: I2C attached devices + /* + * HINT method: I2C attached devices * * This method works for all boards. * Uses a hash of i2c scanned devices. @@ -2935,11 +3016,11 @@ static void em28xx_card_setup(struct em28xx *dev) * If the device can be a webcam, seek for a sensor. * If sensor is not found, then it isn't a webcam. */ - if (dev->board.is_webcam) { + if (dev->is_webcam) { em28xx_detect_sensor(dev); if (dev->em28xx_sensor == EM28XX_NOSENSOR) /* NOTE: error/unknown sensor/no sensor */ - dev->board.is_webcam = 0; + dev->is_webcam = 0; } switch (dev->model) { @@ -2959,9 +3040,9 @@ static void em28xx_card_setup(struct em28xx *dev) * This solution is only valid if they do not share eeprom * hash identities which has not been determined as yet. */ - if (em28xx_hint_board(dev) < 0) + if (em28xx_hint_board(dev) < 0) { dev_err(&dev->intf->dev, "Board not discovered\n"); - else { + } else { em28xx_set_model(dev); em28xx_pre_card_setup(dev); } @@ -2971,7 +3052,7 @@ static void em28xx_card_setup(struct em28xx *dev) } dev_info(&dev->intf->dev, "Identified as %s (card=%d)\n", - dev->board.name, dev->model); + dev->board.name, dev->model); dev->tuner_type = em28xx_boards[dev->model].tuner_type; @@ -2988,7 +3069,7 @@ static void em28xx_card_setup(struct em28xx *dev) { struct tveeprom tv; - if (dev->eedata == NULL) + if (!dev->eedata) break; #if defined(CONFIG_MODULES) && defined(MODULE) request_module("tveeprom"); @@ -3001,15 +3082,15 @@ static void em28xx_card_setup(struct em28xx *dev) if (tv.audio_processor == TVEEPROM_AUDPROC_MSP) { dev->i2s_speed = 2048000; - dev->board.has_msp34xx = 1; + dev->has_msp34xx = 1; } break; } case EM2882_BOARD_KWORLD_ATSC_315U: em28xx_write_reg(dev, 0x0d, 0x42); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); - msleep(10); + usleep_range(10000, 11000); break; case EM2820_BOARD_KWORLD_PVRTV2800RF: /* GPIO enables sound on KWORLD PVR TV 2800RF */ @@ -3034,10 +3115,12 @@ static void em28xx_card_setup(struct em28xx *dev) if (!em28xx_hint_board(dev)) em28xx_set_model(dev); - /* In cases where we had to use a board hint, the call to - em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, - so make the call now so the analog GPIOs are set properly - before probing the i2c bus. */ + /* + * In cases where we had to use a board hint, the call to + * em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, + * so make the call now so the analog GPIOs are set properly + * before probing the i2c bus. + */ em28xx_gpio_set(dev, dev->board.tuner_gpio); em28xx_set_mode(dev, EM28XX_ANALOG_MODE); break; @@ -3059,10 +3142,12 @@ static void em28xx_card_setup(struct em28xx *dev) if (!em28xx_hint_board(dev)) em28xx_set_model(dev); - /* In cases where we had to use a board hint, the call to - em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, - so make the call now so the analog GPIOs are set properly - before probing the i2c bus. */ + /* + * In cases where we had to use a board hint, the call to + * em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, + * so make the call now so the analog GPIOs are set properly + * before probing the i2c bus. + */ em28xx_gpio_set(dev, dev->board.tuner_gpio); em28xx_set_mode(dev, EM28XX_ANALOG_MODE); break; @@ -3147,8 +3232,8 @@ static void request_module_async(struct work_struct *work) */ /* - * Devicdes with an audio-only interface also have a V4L/DVB/RC - * interface. Don't register extensions twice on those devices. + * Devices with an audio-only intf also have a V4L/DVB/RC + * intf. Don't register extensions twice on those devices. */ if (dev->is_audio_only) { #if defined(CONFIG_MODULES) && defined(MODULE) @@ -3209,7 +3294,6 @@ static int em28xx_media_device_init(struct em28xx *dev, static void em28xx_unregister_media_device(struct em28xx *dev) { - #ifdef CONFIG_MEDIA_CONTROLLER if (dev->media_dev) { media_device_unregister(dev->media_dev); @@ -3224,7 +3308,7 @@ static void em28xx_unregister_media_device(struct em28xx *dev) * em28xx_release_resources() * unregisters the v4l2,i2c and usb devices * called when the device gets disconnected or at module unload -*/ + */ static void em28xx_release_resources(struct em28xx *dev) { struct usb_device *udev = interface_to_usbdev(dev->intf); @@ -3239,7 +3323,8 @@ static void em28xx_release_resources(struct em28xx *dev) em28xx_i2c_unregister(dev, 1); em28xx_i2c_unregister(dev, 0); - usb_put_dev(udev); + if (dev->ts == PRIMARY_TS) + usb_put_dev(udev); /* Mark device as unused */ clear_bit(dev->devno, em28xx_devused); @@ -3273,13 +3358,13 @@ EXPORT_SYMBOL_GPL(em28xx_free_device); * allocates and inits the device structs, registers i2c bus and v4l device */ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, - struct usb_interface *interface, + struct usb_interface *intf, int minor) { int retval; const char *chip_name = NULL; - dev->intf = interface; + dev->intf = intf; mutex_init(&dev->ctrl_urb_lock); spin_lock_init(&dev->slock); @@ -3382,17 +3467,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, em28xx_pre_card_setup(dev); - if (!dev->board.is_em2800) { - /* Resets I2C speed */ - retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); - if (retval < 0) { - dev_err(&dev->intf->dev, - "%s: em28xx_write_reg failed! retval [%d]\n", - __func__, retval); - return retval; - } - } - rt_mutex_init(&dev->i2c_bus_lock); /* register i2c bus 0 */ @@ -3417,8 +3491,8 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { dev_err(&dev->intf->dev, - "%s: em28xx_i2c_register bus 1 - error [%d]!\n", - __func__, retval); + "%s: em28xx_i2c_register bus 1 - error [%d]!\n", + __func__, retval); em28xx_i2c_unregister(dev, 0); @@ -3432,14 +3506,147 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, return 0; } +static int em28xx_duplicate_dev(struct em28xx *dev) +{ + int nr; + struct em28xx *sec_dev = kzalloc(sizeof(*sec_dev), GFP_KERNEL); + + if (!sec_dev) { + dev->dev_next = NULL; + return -ENOMEM; + } + memcpy(sec_dev, dev, sizeof(*sec_dev)); + /* Check to see next free device and mark as used */ + do { + nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); + if (nr >= EM28XX_MAXBOARDS) { + /* No free device slots */ + dev_warn(&dev->intf->dev, ": Supports only %i em28xx boards.\n", + EM28XX_MAXBOARDS); + kfree(sec_dev); + dev->dev_next = NULL; + return -ENOMEM; + } + } while (test_and_set_bit(nr, em28xx_devused)); + sec_dev->devno = nr; + snprintf(sec_dev->name, 28, "em28xx #%d", nr); + sec_dev->dev_next = NULL; + dev->dev_next = sec_dev; + return 0; +} + /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) +static void em28xx_check_usb_descriptor(struct em28xx *dev, + struct usb_device *udev, + struct usb_interface *intf, + int alt, int ep, + bool *has_vendor_audio, + bool *has_video, + bool *has_dvb) +{ + const struct usb_endpoint_descriptor *e; + int sizedescr, size; + + /* + * NOTE: + * + * Old logic with support for isoc transfers only was: + * 0x82 isoc => analog + * 0x83 isoc => audio + * 0x84 isoc => digital + * + * New logic with support for bulk transfers + * 0x82 isoc => analog + * 0x82 bulk => analog + * 0x83 isoc* => audio + * 0x84 isoc => digital + * 0x84 bulk => analog or digital** + * 0x85 isoc => digital TS2 + * 0x85 bulk => digital TS2 + * (*: audio should always be isoc) + * (**: analog, if ep 0x82 is isoc, otherwise digital) + * + * The new logic preserves backwards compatibility and + * reflects the endpoint configurations we have seen + * so far. But there might be devices for which this + * logic is not sufficient... + */ + + e = &intf->altsetting[alt].endpoint[ep].desc; + + if (!usb_endpoint_dir_in(e)) + return; + + sizedescr = le16_to_cpu(e->wMaxPacketSize); + size = sizedescr & 0x7ff; + + if (udev->speed == USB_SPEED_HIGH) + size = size * hb_mult(sizedescr); + + /* Only inspect input endpoints */ + + switch (e->bEndpointAddress) { + case 0x82: + *has_video = true; + if (usb_endpoint_xfer_isoc(e)) { + dev->analog_ep_isoc = e->bEndpointAddress; + dev->alt_max_pkt_size_isoc[alt] = size; + } else if (usb_endpoint_xfer_bulk(e)) { + dev->analog_ep_bulk = e->bEndpointAddress; + } + return; + case 0x83: + if (usb_endpoint_xfer_isoc(e)) + *has_vendor_audio = true; + else + dev_err(&intf->dev, + "error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); + return; + case 0x84: + if (*has_video && (usb_endpoint_xfer_bulk(e))) { + dev->analog_ep_bulk = e->bEndpointAddress; + } else { + if (usb_endpoint_xfer_isoc(e)) { + if (size > dev->dvb_max_pkt_size_isoc) { + /* + * 2) some manufacturers (e.g. Terratec) + * disable endpoints by setting + * wMaxPacketSize to 0 bytes for all + * alt settings. So far, we've seen + * this for DVB isoc endpoints only. + */ + *has_dvb = true; + dev->dvb_ep_isoc = e->bEndpointAddress; + dev->dvb_max_pkt_size_isoc = size; + dev->dvb_alt_isoc = alt; + } + } else { + *has_dvb = true; + dev->dvb_ep_bulk = e->bEndpointAddress; + } + } + return; + case 0x85: + if (usb_endpoint_xfer_isoc(e)) { + if (size > dev->dvb_max_pkt_size_isoc_ts2) { + dev->dvb_ep_isoc_ts2 = e->bEndpointAddress; + dev->dvb_max_pkt_size_isoc_ts2 = size; + dev->dvb_alt_isoc = alt; + } + } else { + dev->dvb_ep_bulk_ts2 = e->bEndpointAddress; + } + return; + } +} + /* * em28xx_usb_probe() * checks for supported devices */ -static int em28xx_usb_probe(struct usb_interface *interface, +static int em28xx_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev; @@ -3447,17 +3654,17 @@ static int em28xx_usb_probe(struct usb_interface *interface, int retval; bool has_vendor_audio = false, has_video = false, has_dvb = false; int i, nr, try_bulk; - const int ifnum = interface->altsetting[0].desc.bInterfaceNumber; + const int ifnum = intf->altsetting[0].desc.bInterfaceNumber; char *speed; - udev = usb_get_dev(interface_to_usbdev(interface)); + udev = usb_get_dev(interface_to_usbdev(intf)); /* Check to see next free device and mark as used */ do { nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); if (nr >= EM28XX_MAXBOARDS) { /* No free device slots */ - dev_err(&interface->dev, + dev_err(&intf->dev, "Driver supports up to %i em28xx boards.\n", EM28XX_MAXBOARDS); retval = -ENOMEM; @@ -3466,13 +3673,13 @@ static int em28xx_usb_probe(struct usb_interface *interface, } while (test_and_set_bit(nr, em28xx_devused)); /* Don't register audio interfaces */ - if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { - dev_err(&interface->dev, + if (intf->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { + dev_err(&intf->dev, "audio device (%04x:%04x): interface %i, class %i\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), ifnum, - interface->altsetting[0].desc.bInterfaceClass); + intf->altsetting[0].desc.bInterfaceClass); retval = -ENODEV; goto err; @@ -3480,106 +3687,33 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { + if (!dev) { retval = -ENOMEM; goto err; } /* compute alternate max packet sizes */ - dev->alt_max_pkt_size_isoc = - kmalloc(sizeof(dev->alt_max_pkt_size_isoc[0]) * - interface->num_altsetting, GFP_KERNEL); - if (dev->alt_max_pkt_size_isoc == NULL) { + dev->alt_max_pkt_size_isoc = kcalloc(intf->num_altsetting, + sizeof(dev->alt_max_pkt_size_isoc[0]), + GFP_KERNEL); + if (!dev->alt_max_pkt_size_isoc) { kfree(dev); retval = -ENOMEM; goto err; } /* Get endpoints */ - for (i = 0; i < interface->num_altsetting; i++) { + for (i = 0; i < intf->num_altsetting; i++) { int ep; - for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) { - const struct usb_endpoint_descriptor *e; - int sizedescr, size; - - e = &interface->altsetting[i].endpoint[ep].desc; - - sizedescr = le16_to_cpu(e->wMaxPacketSize); - size = sizedescr & 0x7ff; - - if (udev->speed == USB_SPEED_HIGH) - size = size * hb_mult(sizedescr); - - if (usb_endpoint_dir_in(e)) { - switch (e->bEndpointAddress) { - case 0x82: - has_video = true; - if (usb_endpoint_xfer_isoc(e)) { - dev->analog_ep_isoc = - e->bEndpointAddress; - dev->alt_max_pkt_size_isoc[i] = size; - } else if (usb_endpoint_xfer_bulk(e)) { - dev->analog_ep_bulk = - e->bEndpointAddress; - } - break; - case 0x83: - if (usb_endpoint_xfer_isoc(e)) { - has_vendor_audio = true; - } else { - dev_err(&interface->dev, - "error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); - } - break; - case 0x84: - if (has_video && - (usb_endpoint_xfer_bulk(e))) { - dev->analog_ep_bulk = - e->bEndpointAddress; - } else { - if (usb_endpoint_xfer_isoc(e)) { - if (size > dev->dvb_max_pkt_size_isoc) { - has_dvb = true; /* see NOTE (~) */ - dev->dvb_ep_isoc = e->bEndpointAddress; - dev->dvb_max_pkt_size_isoc = size; - dev->dvb_alt_isoc = i; - } - } else { - has_dvb = true; - dev->dvb_ep_bulk = e->bEndpointAddress; - } - } - break; - } - } - /* NOTE: - * Old logic with support for isoc transfers only was: - * 0x82 isoc => analog - * 0x83 isoc => audio - * 0x84 isoc => digital - * - * New logic with support for bulk transfers - * 0x82 isoc => analog - * 0x82 bulk => analog - * 0x83 isoc* => audio - * 0x84 isoc => digital - * 0x84 bulk => analog or digital** - * (*: audio should always be isoc) - * (**: analog, if ep 0x82 is isoc, otherwise digital) - * - * The new logic preserves backwards compatibility and - * reflects the endpoint configurations we have seen - * so far. But there might be devices for which this - * logic is not sufficient... - */ - /* - * NOTE (~): some manufacturers (e.g. Terratec) disable - * endpoints by setting wMaxPacketSize to 0 bytes for - * all alt settings. So far, we've seen this for - * DVB isoc endpoints only. - */ - } + for (ep = 0; + ep < intf->altsetting[i].desc.bNumEndpoints; + ep++) + em28xx_check_usb_descriptor(dev, udev, intf, + i, ep, + &has_vendor_audio, + &has_video, + &has_dvb); } if (!(has_vendor_audio || has_video || has_dvb)) { @@ -3602,7 +3736,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - dev_err(&interface->dev, + dev_err(&intf->dev, "New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", udev->manufacturer ? udev->manufacturer : "", udev->product ? udev->product : "", @@ -3610,7 +3744,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), ifnum, - interface->altsetting->desc.bInterfaceNumber); + intf->altsetting->desc.bInterfaceNumber); /* * Make sure we have 480 Mbps of bandwidth, otherwise things like @@ -3618,8 +3752,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, * not enough even for most Digital TV streams. */ if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { - dev_err(&interface->dev, "Device initialization failed.\n"); - dev_err(&interface->dev, + dev_err(&intf->dev, "Device initialization failed.\n"); + dev_err(&intf->dev, "Device must be connected to a high-speed USB 2.0 port.\n"); retval = -ENODEV; goto err_free; @@ -3632,53 +3766,56 @@ static int em28xx_usb_probe(struct usb_interface *interface, dev->has_video = has_video; dev->ifnum = ifnum; + dev->ts = PRIMARY_TS; + snprintf(dev->name, 28, "em28xx"); + dev->dev_next = NULL; + if (has_vendor_audio) { - dev_err(&interface->dev, + dev_err(&intf->dev, "Audio interface %i found (Vendor Class)\n", ifnum); dev->usb_audio_type = EM28XX_USB_AUDIO_VENDOR; } - /* Checks if audio is provided by a USB Audio Class interface */ + /* Checks if audio is provided by a USB Audio Class intf */ for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { struct usb_interface *uif = udev->config->interface[i]; if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { if (has_vendor_audio) - dev_err(&interface->dev, + dev_err(&intf->dev, "em28xx: device seems to have vendor AND usb audio class interfaces !\n" - "\t\tThe vendor interface will be ignored. Please contact the developers <linux-media@vger.kernel.org>\n"); + "\t\tThe vendor interface will be ignored. Please contact the developers <linux-media@vger.kernel.org>\n"); dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS; break; } } if (has_video) - dev_err(&interface->dev, "Video interface %i found:%s%s\n", + dev_err(&intf->dev, "Video interface %i found:%s%s\n", ifnum, dev->analog_ep_bulk ? " bulk" : "", dev->analog_ep_isoc ? " isoc" : ""); if (has_dvb) - dev_err(&interface->dev, "DVB interface %i found:%s%s\n", + dev_err(&intf->dev, "DVB interface %i found:%s%s\n", ifnum, dev->dvb_ep_bulk ? " bulk" : "", dev->dvb_ep_isoc ? " isoc" : ""); - dev->num_alt = interface->num_altsetting; + dev->num_alt = intf->num_altsetting; - if ((unsigned)card[nr] < em28xx_bcount) + if ((unsigned int)card[nr] < em28xx_bcount) dev->model = card[nr]; - /* save our data pointer in this interface device */ - usb_set_intfdata(interface, dev); + /* save our data pointer in this intf device */ + usb_set_intfdata(intf, dev); /* allocate device struct and check if the device is a webcam */ mutex_init(&dev->lock); - retval = em28xx_init_dev(dev, udev, interface, nr); - if (retval) { + retval = em28xx_init_dev(dev, udev, intf, nr); + if (retval) goto err_free; - } if (usb_xfer_mode < 0) { - if (dev->board.is_webcam) + if (dev->is_webcam) try_bulk = 1; else try_bulk = 0; @@ -3690,8 +3827,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (has_video && dev->board.decoder == EM28XX_NODECODER && dev->em28xx_sensor == EM28XX_NOSENSOR) { - - dev_err(&interface->dev, + dev_err(&intf->dev, "Currently, V4L2 is not supported on this model\n"); has_video = false; dev->has_video = false; @@ -3701,16 +3837,75 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (has_video) { if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) dev->analog_xfer_bulk = 1; - dev_err(&interface->dev, "analog set to %s mode.\n", + dev_err(&intf->dev, "analog set to %s mode.\n", dev->analog_xfer_bulk ? "bulk" : "isoc"); } if (has_dvb) { if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) dev->dvb_xfer_bulk = 1; - dev_err(&interface->dev, "dvb set to %s mode.\n", + dev_err(&intf->dev, "dvb set to %s mode.\n", dev->dvb_xfer_bulk ? "bulk" : "isoc"); } + if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) { + dev->dev_next->ts = SECONDARY_TS; + dev->dev_next->alt = -1; + dev->dev_next->is_audio_only = has_vendor_audio && + !(has_video || has_dvb); + dev->dev_next->has_video = false; + dev->dev_next->ifnum = ifnum; + dev->dev_next->model = id->driver_info; + + mutex_init(&dev->dev_next->lock); + retval = em28xx_init_dev(dev->dev_next, udev, intf, + dev->dev_next->devno); + if (retval) + goto err_free; + + dev->dev_next->board.ir_codes = NULL; /* No IR for 2nd tuner */ + dev->dev_next->board.has_ir_i2c = 0; /* No IR for 2nd tuner */ + + if (usb_xfer_mode < 0) { + if (dev->dev_next->is_webcam) + try_bulk = 1; + else + try_bulk = 0; + } else { + try_bulk = usb_xfer_mode > 0; + } + + /* Select USB transfer types to use */ + if (has_dvb) { + if (!dev->dvb_ep_isoc_ts2 || + (try_bulk && dev->dvb_ep_bulk_ts2)) + dev->dev_next->dvb_xfer_bulk = 1; + dev_info(&dev->intf->dev, "dvb ts2 set to %s mode.\n", + dev->dev_next->dvb_xfer_bulk ? "bulk" : "isoc"); + } + + dev->dev_next->dvb_ep_isoc = dev->dvb_ep_isoc_ts2; + dev->dev_next->dvb_ep_bulk = dev->dvb_ep_bulk_ts2; + dev->dev_next->dvb_max_pkt_size_isoc = dev->dvb_max_pkt_size_isoc_ts2; + dev->dev_next->dvb_alt_isoc = dev->dvb_alt_isoc; + + /* Configuare hardware to support TS2*/ + if (dev->dvb_xfer_bulk) { + /* The ep4 and ep5 are configuared for BULK */ + em28xx_write_reg(dev, 0x0b, 0x96); + mdelay(100); + em28xx_write_reg(dev, 0x0b, 0x80); + mdelay(100); + } else { + /* The ep4 and ep5 are configuared for ISO */ + em28xx_write_reg(dev, 0x0b, 0x96); + mdelay(100); + em28xx_write_reg(dev, 0x0b, 0x82); + mdelay(100); + } + + kref_init(&dev->dev_next->ref); + } + kref_init(&dev->ref); request_modules(dev); @@ -3743,45 +3938,59 @@ err_no_slot: * called when the device gets disconnected * video device will be unregistered on v4l2_close in case it is still open */ -static void em28xx_usb_disconnect(struct usb_interface *interface) +static void em28xx_usb_disconnect(struct usb_interface *intf) { struct em28xx *dev; - dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); + dev = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); if (!dev) return; + if (dev->dev_next) { + dev->dev_next->disconnected = 1; + dev_info(&dev->intf->dev, "Disconnecting %s\n", + dev->dev_next->name); + flush_request_modules(dev->dev_next); + } + dev->disconnected = 1; - dev_err(&dev->intf->dev, "Disconnecting\n"); + dev_err(&dev->intf->dev, "Disconnecting %s\n", dev->name); flush_request_modules(dev); em28xx_close_extension(dev); + if (dev->dev_next) + em28xx_release_resources(dev->dev_next); em28xx_release_resources(dev); + + if (dev->dev_next) { + kref_put(&dev->dev_next->ref, em28xx_free_device); + dev->dev_next = NULL; + } kref_put(&dev->ref, em28xx_free_device); } -static int em28xx_usb_suspend(struct usb_interface *interface, +static int em28xx_usb_suspend(struct usb_interface *intf, pm_message_t message) { struct em28xx *dev; - dev = usb_get_intfdata(interface); + dev = usb_get_intfdata(intf); if (!dev) return 0; em28xx_suspend_extension(dev); return 0; } -static int em28xx_usb_resume(struct usb_interface *interface) +static int em28xx_usb_resume(struct usb_interface *intf) { struct em28xx *dev; - dev = usb_get_intfdata(interface); + dev = usb_get_intfdata(intf); if (!dev) return 0; em28xx_resume_extension(dev); diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 1d0d8cc06103..36d341fb65dd 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -1,26 +1,22 @@ -/* - em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - - Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> - Markus Rechberger <mrechberger@gmail.com> - Mauro Carvalho Chehab <mchehab@infradead.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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices +// +// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> +// Markus Rechberger <mrechberger@gmail.com> +// Mauro Carvalho Chehab <mchehab@infradead.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" @@ -41,7 +37,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_VERSION(EM28XX_VERSION); /* #define ENABLE_DEBUG_ISOC_FRAMES */ @@ -60,7 +56,6 @@ static unsigned int reg_debug; module_param(reg_debug, int, 0644); MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); - #define em28xx_regdbg(fmt, arg...) do { \ if (reg_debug) \ dev_printk(KERN_DEBUG, &dev->intf->dev, \ @@ -97,10 +92,11 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, 0x0000, reg, dev->urb_buf, len, HZ); if (ret < 0) { em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n", - pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - req, 0, 0, - reg & 0xff, reg >> 8, - len & 0xff, len >> 8, ret); + pipe, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + req, 0, 0, + reg & 0xff, reg >> 8, + len & 0xff, len >> 8, ret); mutex_unlock(&dev->ctrl_urb_lock); return usb_translate_errors(ret); } @@ -111,10 +107,10 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, mutex_unlock(&dev->ctrl_urb_lock); em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x <<< %*ph\n", - pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - req, 0, 0, - reg & 0xff, reg >> 8, - len & 0xff, len >> 8, len, buf); + pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + req, 0, 0, + reg & 0xff, reg >> 8, + len & 0xff, len >> 8, len, buf); return ret; } @@ -155,7 +151,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, if (dev->disconnected) return -ENODEV; - if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) + if (len < 1 || len > URB_MAX_CTRL_SIZE) return -EINVAL; mutex_lock(&dev->ctrl_urb_lock); @@ -341,8 +337,9 @@ static int set_ac97_input(struct em28xx *dev) int ret, i; enum em28xx_amux amux = dev->ctl_ainput; - /* EM28XX_AMUX_VIDEO2 is a special case used to indicate that - em28xx should point to LINE IN, while AC97 should use VIDEO + /* + * EM28XX_AMUX_VIDEO2 is a special case used to indicate that + * em28xx should point to LINE IN, while AC97 should use VIDEO */ if (amux == EM28XX_AMUX_VIDEO2) amux = EM28XX_AMUX_VIDEO; @@ -378,9 +375,9 @@ static int em28xx_set_audio_source(struct em28xx *dev) return ret; } - if (dev->board.has_msp34xx) + if (dev->has_msp34xx) { input = EM28XX_AUDIO_SRC_TUNER; - else { + } else { switch (dev->ctl_ainput) { case EM28XX_AMUX_VIDEO: input = EM28XX_AUDIO_SRC_TUNER; @@ -399,7 +396,7 @@ static int em28xx_set_audio_source(struct em28xx *dev) ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0); if (ret < 0) return ret; - msleep(5); + usleep_range(10000, 11000); switch (dev->audio_mode.ac97) { case EM28XX_NO_AC97: @@ -432,8 +429,9 @@ int em28xx_audio_analog_set(struct em28xx *dev) if (dev->int_audio_type == EM28XX_INT_AUDIO_NONE) return 0; - /* It is assumed that all devices use master volume for output. - It would be possible to use also line output. + /* + * It is assumed that all devices use master volume for output. + * It would be possible to use also line output. */ if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { /* Mute all outputs */ @@ -453,7 +451,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); if (ret < 0) return ret; - msleep(10); + usleep_range(10000, 11000); /* Selects the proper audio input */ ret = em28xx_set_audio_source(dev); @@ -487,8 +485,10 @@ int em28xx_audio_analog_set(struct em28xx *dev) if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { int sel = ac97_return_record_select(dev->ctl_aoutput); - /* Use the same input for both left and right - channels */ + /* + * Use the same input for both left and right + * channels + */ sel |= (sel << 8); em28xx_write_ac97(dev, AC97_REC_SEL, sel); @@ -539,7 +539,7 @@ int em28xx_audio_setup(struct em28xx *dev) else i2s_samplerates = 3; dev_info(&dev->intf->dev, "I2S Audio (%d sample rate(s))\n", - i2s_samplerates); + i2s_samplerates); /* Skip the code that does AC97 vendor detection */ dev->audio_mode.ac97 = EM28XX_NO_AC97; goto init_audio; @@ -579,7 +579,7 @@ int em28xx_audio_setup(struct em28xx *dev) dev_warn(&dev->intf->dev, "AC97 features = 0x%04x\n", feat); /* Try to identify what audio processor we have */ - if (((vid == 0xffffffff) || (vid == 0x83847650)) && (feat == 0x6a90)) + if ((vid == 0xffffffff || vid == 0x83847650) && feat == 0x6a90) dev->audio_mode.ac97 = EM28XX_AC97_EM202; else if ((vid >> 8) == 0x838476) dev->audio_mode.ac97 = EM28XX_AC97_SIGMATEL; @@ -638,10 +638,29 @@ int em28xx_capture_start(struct em28xx *dev, int start) dev->chip_id == CHIP_ID_EM28174 || dev->chip_id == CHIP_ID_EM28178) { /* The Transport Stream Enable Register moved in em2874 */ - rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, - start ? - EM2874_TS1_CAPTURE_ENABLE : 0x00, - EM2874_TS1_CAPTURE_ENABLE); + if (dev->dvb_xfer_bulk) { + /* Max Tx Size = 188 * 256 = 48128 - LCM(188,512) * 2 */ + em28xx_write_reg(dev, (dev->ts == PRIMARY_TS) ? + EM2874_R5D_TS1_PKT_SIZE : + EM2874_R5E_TS2_PKT_SIZE, + 0xff); + } else { + /* ISOC Maximum Transfer Size = 188 * 5 */ + em28xx_write_reg(dev, (dev->ts == PRIMARY_TS) ? + EM2874_R5D_TS1_PKT_SIZE : + EM2874_R5E_TS2_PKT_SIZE, + dev->dvb_max_pkt_size_isoc / 188); + } + if (dev->ts == PRIMARY_TS) + rc = em28xx_write_reg_bits(dev, + EM2874_R5F_TS_ENABLE, + start ? EM2874_TS1_CAPTURE_ENABLE : 0x00, + EM2874_TS1_CAPTURE_ENABLE); + else + rc = em28xx_write_reg_bits(dev, + EM2874_R5F_TS_ENABLE, + start ? EM2874_TS2_CAPTURE_ENABLE : 0x00, + EM2874_TS2_CAPTURE_ENABLE); } else { /* FIXME: which is the best order? */ /* video registers are sampled by VREF */ @@ -651,7 +670,7 @@ int em28xx_capture_start(struct em28xx *dev, int start) return rc; if (start) { - if (dev->board.is_webcam) + if (dev->is_webcam) rc = em28xx_write_reg(dev, 0x13, 0x0c); /* Enable video capture */ @@ -670,7 +689,7 @@ int em28xx_capture_start(struct em28xx *dev, int start) if (rc < 0) return rc; - msleep(6); + usleep_range(10000, 11000); } else { /* disable video capture */ rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27); @@ -691,7 +710,7 @@ int em28xx_capture_start(struct em28xx *dev, int start) return rc; } -int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) +int em28xx_gpio_set(struct em28xx *dev, const struct em28xx_reg_seq *gpio) { int rc = 0; @@ -704,7 +723,7 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); else em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); - msleep(6); + usleep_range(10000, 11000); } /* Send GPIO reset sequences specified at board entry */ @@ -748,9 +767,9 @@ int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) } EXPORT_SYMBOL_GPL(em28xx_set_mode); -/* ------------------------------------------------------------------ - URB control - ------------------------------------------------------------------*/ +/* + *URB control + */ /* * URB completion handler for isoc/bulk transfers @@ -769,7 +788,7 @@ static void em28xx_irq_callback(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - em28xx_isocdbg("urb completition error %d.\n", urb->status); + em28xx_isocdbg("urb completion error %d.\n", urb->status); break; } @@ -800,11 +819,9 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) { struct urb *urb; struct em28xx_usb_bufs *usb_bufs; - struct usb_device *udev = interface_to_usbdev(dev->intf); int i; - em28xx_isocdbg("em28xx: called em28xx_uninit_usb_xfer in mode %d\n", - mode); + em28xx_isocdbg("called %s in mode %d\n", __func__, mode); if (mode == EM28XX_DIGITAL_MODE) usb_bufs = &dev->usb_ctl.digital_bufs; @@ -819,23 +836,16 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) else usb_unlink_urb(urb); - if (usb_bufs->transfer_buffer[i]) { - usb_free_coherent(udev, - urb->transfer_buffer_length, - usb_bufs->transfer_buffer[i], - urb->transfer_dma); - } usb_free_urb(urb); usb_bufs->urb[i] = NULL; } - usb_bufs->transfer_buffer[i] = NULL; } kfree(usb_bufs->urb); - kfree(usb_bufs->transfer_buffer); + kfree(usb_bufs->buf); usb_bufs->urb = NULL; - usb_bufs->transfer_buffer = NULL; + usb_bufs->buf = NULL; usb_bufs->num_bufs = 0; em28xx_capture_start(dev, 0); @@ -851,7 +861,7 @@ void em28xx_stop_urbs(struct em28xx *dev) struct urb *urb; struct em28xx_usb_bufs *isoc_bufs = &dev->usb_ctl.digital_bufs; - em28xx_isocdbg("em28xx: called em28xx_stop_urbs\n"); + em28xx_isocdbg("called %s\n", __func__); for (i = 0; i < isoc_bufs->num_bufs; i++) { urb = isoc_bufs->urb[i]; @@ -880,10 +890,12 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, int sb_size, pipe; int j, k; - em28xx_isocdbg("em28xx: called em28xx_alloc_isoc in mode %d\n", mode); + em28xx_isocdbg("em28xx: called %s in mode %d\n", __func__, mode); - /* Check mode and if we have an endpoint for the selected - transfer type, select buffer */ + /* + * Check mode and if we have an endpoint for the selected + * transfer type, select buffer + */ if (mode == EM28XX_DIGITAL_MODE) { if ((xfer_bulk && !dev->dvb_ep_bulk) || (!xfer_bulk && !dev->dvb_ep_isoc)) { @@ -912,14 +924,13 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->num_bufs = num_bufs; - usb_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); + usb_bufs->urb = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!usb_bufs->urb) return -ENOMEM; - usb_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs, - GFP_KERNEL); - if (!usb_bufs->transfer_buffer) { - kfree(usb_bufs->urb); + usb_bufs->buf = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); + if (!usb_bufs->buf) { + kfree(usb_bufs->buf); return -ENOMEM; } @@ -942,37 +953,36 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, } usb_bufs->urb[i] = urb; - usb_bufs->transfer_buffer[i] = usb_alloc_coherent(udev, - sb_size, GFP_KERNEL, &urb->transfer_dma); - if (!usb_bufs->transfer_buffer[i]) { - dev_err(&dev->intf->dev, - "unable to allocate %i bytes for transfer buffer %i%s\n", - sb_size, i, - in_interrupt() ? " while in int" : ""); + usb_bufs->buf[i] = kzalloc(sb_size, GFP_KERNEL); + if (!usb_bufs->buf[i]) { em28xx_uninit_usb_xfer(dev, mode); + + for (i--; i >= 0; i--) + kfree(usb_bufs->buf[i]); + + kfree(usb_bufs->buf); + usb_bufs->buf = NULL; + return -ENOMEM; } - memset(usb_bufs->transfer_buffer[i], 0, sb_size); + + urb->transfer_flags = URB_FREE_BUFFER; if (xfer_bulk) { /* bulk */ pipe = usb_rcvbulkpipe(udev, mode == EM28XX_ANALOG_MODE ? dev->analog_ep_bulk : dev->dvb_ep_bulk); - usb_fill_bulk_urb(urb, udev, pipe, - usb_bufs->transfer_buffer[i], sb_size, - em28xx_irq_callback, dev); - urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; + usb_fill_bulk_urb(urb, udev, pipe, usb_bufs->buf[i], + sb_size, em28xx_irq_callback, dev); } else { /* isoc */ pipe = usb_rcvisocpipe(udev, mode == EM28XX_ANALOG_MODE ? dev->analog_ep_isoc : dev->dvb_ep_isoc); - usb_fill_int_urb(urb, udev, pipe, - usb_bufs->transfer_buffer[i], sb_size, - em28xx_irq_callback, dev, 1); - urb->transfer_flags = URB_ISO_ASAP | - URB_NO_TRANSFER_DMA_MAP; + usb_fill_int_urb(urb, udev, pipe, usb_bufs->buf[i], + sb_size, em28xx_irq_callback, dev, 1); + urb->transfer_flags |= URB_ISO_ASAP; k = 0; for (j = 0; j < usb_bufs->num_packets; j++) { urb->iso_frame_desc[j].offset = k; @@ -1005,8 +1015,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, int rc; int alloc; - em28xx_isocdbg("em28xx: called em28xx_init_usb_xfer in mode %d\n", - mode); + em28xx_isocdbg("em28xx: called %s in mode %d\n", __func__, mode); dev->usb_ctl.urb_data_copy = urb_data_copy; @@ -1077,7 +1086,11 @@ int em28xx_register_extension(struct em28xx_ops *ops) mutex_lock(&em28xx_devlist_mutex); list_add_tail(&ops->next, &em28xx_extension_devlist); list_for_each_entry(dev, &em28xx_devlist, devlist) { - ops->init(dev); + if (ops->init) { + ops->init(dev); + if (dev->dev_next) + ops->init(dev->dev_next); + } } mutex_unlock(&em28xx_devlist_mutex); pr_info("em28xx: Registered (%s) extension\n", ops->name); @@ -1091,7 +1104,11 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(dev, &em28xx_devlist, devlist) { - ops->fini(dev); + if (ops->fini) { + if (dev->dev_next) + ops->fini(dev->dev_next); + ops->fini(dev); + } } list_del(&ops->next); mutex_unlock(&em28xx_devlist_mutex); @@ -1106,8 +1123,11 @@ void em28xx_init_extension(struct em28xx *dev) mutex_lock(&em28xx_devlist_mutex); list_add_tail(&dev->devlist, &em28xx_devlist); list_for_each_entry(ops, &em28xx_extension_devlist, next) { - if (ops->init) + if (ops->init) { ops->init(dev); + if (dev->dev_next) + ops->init(dev->dev_next); + } } mutex_unlock(&em28xx_devlist_mutex); } @@ -1118,8 +1138,11 @@ void em28xx_close_extension(struct em28xx *dev) mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { - if (ops->fini) + if (ops->fini) { + if (dev->dev_next) + ops->fini(dev->dev_next); ops->fini(dev); + } } list_del(&dev->devlist); mutex_unlock(&em28xx_devlist_mutex); @@ -1134,6 +1157,8 @@ int em28xx_suspend_extension(struct em28xx *dev) list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->suspend) ops->suspend(dev); + if (dev->dev_next) + ops->suspend(dev->dev_next); } mutex_unlock(&em28xx_devlist_mutex); return 0; @@ -1148,6 +1173,8 @@ int em28xx_resume_extension(struct em28xx *dev) list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->resume) ops->resume(dev); + if (dev->dev_next) + ops->resume(dev->dev_next); } mutex_unlock(&em28xx_devlist_mutex); return 0; diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 8a81c94a8a27..a54cb8dc52c9 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1,25 +1,25 @@ -/* - DVB device driver for em28xx - - (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> - - (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> - - Fixes for the driver to properly work with HVR-950 - - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick - - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 - - (c) 2008 Aidan Thornton <makosoft@googlemail.com> - - (c) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> - - Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: - (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> - (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] - - 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. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// DVB device driver for em28xx +// +// (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> +// +// (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> +// - Fixes for the driver to properly work with HVR-950 +// - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick +// - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 +// +// (c) 2008 Aidan Thornton <makosoft@googlemail.com> +// +// (c) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> +// +// Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: +// (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> +// (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] +// +// 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 version 2 of the License. #include "em28xx.h" @@ -64,7 +64,7 @@ #include "qm1d1c0042.h" MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION(DRIVER_DESC " - digital TV interface"); MODULE_VERSION(EM28XX_VERSION); @@ -96,7 +96,7 @@ struct em28xx_dvb { struct dvb_net net; /* Due to DRX-K - probably need changes */ - int (*gate_ctrl)(struct dvb_frontend *, int); + int (*gate_ctrl)(struct dvb_frontend *fe, int gate); struct semaphore pll_mutex; bool dont_attach_fe1; int lna_gpio; @@ -199,7 +199,6 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb) int rc; struct em28xx_i2c_bus *i2c_bus = dvb->adapter.priv; struct em28xx *dev = i2c_bus->dev; - struct usb_device *udev = interface_to_usbdev(dev->intf); int dvb_max_packet_size, packet_multiplier, dvb_alt; if (dev->dvb_xfer_bulk) { @@ -218,7 +217,6 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb) dvb_alt = dev->dvb_alt_isoc; } - usb_set_interface(udev, dev->ifnum, dvb_alt); rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); if (rc < 0) return rc; @@ -278,14 +276,13 @@ static int em28xx_stop_feed(struct dvb_demux_feed *feed) mutex_lock(&dvb->lock); dvb->nfeeds--; - if (0 == dvb->nfeeds) + if (!dvb->nfeeds) err = em28xx_stop_streaming(dvb); mutex_unlock(&dvb->lock); return err; } - /* ------------------------------------------------------------------ */ static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) { @@ -358,7 +355,7 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { .gpio = S5H1409_GPIO_OFF, .inversion = S5H1409_INVERSION_OFF, .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK + .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK }; static struct tda18271_std_map kworld_a340_std_map = { @@ -514,14 +511,15 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) em28xx_gpio_set(dev, hauppauge_hvr930c_init); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); - msleep(10); + usleep_range(10000, 11000); dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], + regs[i].r, regs[i].len); em28xx_gpio_set(dev, hauppauge_hvr930c_end); msleep(100); @@ -530,8 +528,7 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) msleep(30); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); - msleep(10); - + usleep_range(10000, 11000); } static void terratec_h5_init(struct em28xx *dev) @@ -571,14 +568,15 @@ static void terratec_h5_init(struct em28xx *dev) em28xx_gpio_set(dev, terratec_h5_init); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); - msleep(10); + usleep_range(10000, 11000); dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], + regs[i].r, regs[i].len); em28xx_gpio_set(dev, terratec_h5_end); }; @@ -624,14 +622,15 @@ static void terratec_htc_stick_init(struct em28xx *dev) em28xx_gpio_set(dev, terratec_htc_stick_init); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); - msleep(10); + usleep_range(10000, 11000); dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], + regs[i].r, regs[i].len); em28xx_gpio_set(dev, terratec_htc_stick_end); }; @@ -682,14 +681,15 @@ static void terratec_htc_usb_xs_init(struct em28xx *dev) em28xx_gpio_set(dev, terratec_htc_usb_xs_init); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); - msleep(10); + usleep_range(10000, 11000); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); - msleep(10); + usleep_range(10000, 11000); dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], + regs[i].r, regs[i].len); em28xx_gpio_set(dev, terratec_htc_usb_xs_end); }; @@ -718,7 +718,8 @@ static void pctv_520e_init(struct em28xx *dev) dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; /* 0x41 */ for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], + regs[i].r, regs[i].len); }; static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) @@ -780,7 +781,7 @@ static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) static u8 tuner_go[] = { TUNER_GO, 0x01}; mt352_write(fe, clock_config, sizeof(clock_config)); - udelay(200); + usleep_range(200, 250); mt352_write(fe, reset, sizeof(reset)); mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); mt352_write(fe, agc_cfg, sizeof(agc_cfg)); @@ -840,8 +841,8 @@ static void px_bcud_init(struct em28xx *dev) /* sleeping ISDB-T */ dev->dvb->i2c_client_demod->addr = 0x14; for (i = 0; i < ARRAY_SIZE(regs1); i++) - i2c_master_send(dev->dvb->i2c_client_demod, regs1[i].r, - regs1[i].len); + i2c_master_send(dev->dvb->i2c_client_demod, + regs1[i].r, regs1[i].len); /* sleeping ISDB-S */ dev->dvb->i2c_client_demod->addr = 0x15; for (i = 0; i < ARRAY_SIZE(regs2); i++) @@ -934,7 +935,7 @@ static struct lgdt3306a_config hauppauge_01595_lgdt3306a_config = { /* ------------------------------------------------------------------ */ -static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) +static noinline_for_stack int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) { struct dvb_frontend *fe; struct xc2028_config cfg; @@ -1077,7 +1078,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); /* If the analog part won't create RF connectors, DVB will do it */ - if (!dev->has_video || (dev->tuner_type == TUNER_ABSENT)) + if (!dev->has_video || dev->tuner_type == TUNER_ABSENT) create_rf_connector = true; result = dvb_create_media_graph(&dvb->adapter, create_rf_connector); @@ -1126,10 +1127,285 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb) dvb_unregister_adapter(&dvb->adapter); } +static int em28174_dvb_init_pctv_460e(struct em28xx *dev) +{ + struct em28xx_dvb *dvb = dev->dvb; + struct tda10071_platform_data tda10071_pdata = {}; + struct a8293_platform_data a8293_pdata = {}; + + /* attach demod + tuner combo */ + tda10071_pdata.clk = 40444000; /* 40.444 MHz */ + tda10071_pdata.i2c_wr_max = 64; + tda10071_pdata.ts_mode = TDA10071_TS_SERIAL; + tda10071_pdata.pll_multiplier = 20; + tda10071_pdata.tuner_i2c_addr = 0x14; + + dvb->i2c_client_demod = dvb_module_probe("tda10071", "tda10071_cx24118", + &dev->i2c_adap[dev->def_i2c_bus], + 0x55, &tda10071_pdata); + if (!dvb->i2c_client_demod) + return -ENODEV; + + dvb->fe[0] = tda10071_pdata.get_dvb_frontend(dvb->i2c_client_demod); + + /* attach SEC */ + a8293_pdata.dvb_frontend = dvb->fe[0]; + + dvb->i2c_client_sec = dvb_module_probe("a8293", NULL, + &dev->i2c_adap[dev->def_i2c_bus], + 0x08, &a8293_pdata); + if (!dvb->i2c_client_sec) { + dvb_module_release(dvb->i2c_client_demod); + return -ENODEV; + } + + return 0; +} + +static int em28178_dvb_init_pctv_461e(struct em28xx *dev) +{ + struct em28xx_dvb *dvb = dev->dvb; + struct i2c_adapter *i2c_adapter; + struct m88ds3103_platform_data m88ds3103_pdata = {}; + struct ts2020_config ts2020_config = {}; + struct a8293_platform_data a8293_pdata = {}; + + /* attach demod */ + m88ds3103_pdata.clk = 27000000; + m88ds3103_pdata.i2c_wr_max = 33; + m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL; + m88ds3103_pdata.ts_clk = 16000; + m88ds3103_pdata.ts_clk_pol = 1; + m88ds3103_pdata.agc = 0x99; + + dvb->i2c_client_demod = dvb_module_probe("m88ds3103", NULL, + &dev->i2c_adap[dev->def_i2c_bus], + 0x68, &m88ds3103_pdata); + if (!dvb->i2c_client_demod) + return -ENODEV; + + dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(dvb->i2c_client_demod); + i2c_adapter = m88ds3103_pdata.get_i2c_adapter(dvb->i2c_client_demod); + + /* attach tuner */ + ts2020_config.fe = dvb->fe[0]; + + dvb->i2c_client_tuner = dvb_module_probe("ts2020", "ts2022", + i2c_adapter, + 0x60, &ts2020_config); + if (!dvb->i2c_client_tuner) { + dvb_module_release(dvb->i2c_client_demod); + return -ENODEV; + } + + /* delegate signal strength measurement to tuner */ + dvb->fe[0]->ops.read_signal_strength = + dvb->fe[0]->ops.tuner_ops.get_rf_strength; + + /* attach SEC */ + a8293_pdata.dvb_frontend = dvb->fe[0]; + dvb->i2c_client_sec = dvb_module_probe("a8293", NULL, + &dev->i2c_adap[dev->def_i2c_bus], + 0x08, &a8293_pdata); + if (!dvb->i2c_client_sec) { + dvb_module_release(dvb->i2c_client_tuner); + dvb_module_release(dvb->i2c_client_demod); + return -ENODEV; + } + + return 0; +} + +static int em28178_dvb_init_pctv_292e(struct em28xx *dev) +{ + struct em28xx_dvb *dvb = dev->dvb; + struct i2c_adapter *adapter; + struct si2168_config si2168_config = {}; + struct si2157_config si2157_config = {}; + + /* attach demod */ + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &dvb->fe[0]; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + si2168_config.spectral_inversion = true; + + dvb->i2c_client_demod = dvb_module_probe("si2168", NULL, + &dev->i2c_adap[dev->def_i2c_bus], + 0x64, &si2168_config); + if (!dvb->i2c_client_demod) + return -ENODEV; + + /* attach tuner */ + si2157_config.fe = dvb->fe[0]; + si2157_config.if_port = 1; +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + si2157_config.mdev = dev->media_dev; +#endif + dvb->i2c_client_tuner = dvb_module_probe("si2157", NULL, + adapter, + 0x60, &si2157_config); + if (!dvb->i2c_client_tuner) { + dvb_module_release(dvb->i2c_client_demod); + return -ENODEV; + } + dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; + + return 0; +} + +static int em28178_dvb_init_terratec_t2_stick_hd(struct em28xx *dev) +{ + struct em28xx_dvb *dvb = dev->dvb; + struct i2c_adapter *adapter; + struct si2168_config si2168_config = {}; + struct si2157_config si2157_config = {}; + + /* attach demod */ + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &dvb->fe[0]; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + + dvb->i2c_client_demod = dvb_module_probe("si2168", NULL, + &dev->i2c_adap[dev->def_i2c_bus], + 0x64, &si2168_config); + if (!dvb->i2c_client_demod) + return -ENODEV; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = dvb->fe[0]; + si2157_config.if_port = 0; +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + si2157_config.mdev = dev->media_dev; +#endif + dvb->i2c_client_tuner = dvb_module_probe("si2157", "si2146", + adapter, + 0x60, &si2157_config); + if (!dvb->i2c_client_tuner) { + dvb_module_release(dvb->i2c_client_demod); + return -ENODEV; + } + + return 0; +} + +static int em28178_dvb_init_plex_px_bcud(struct em28xx *dev) +{ + struct em28xx_dvb *dvb = dev->dvb; + struct tc90522_config tc90522_config = {}; + struct qm1d1c0042_config qm1d1c0042_config = {}; + + /* attach demod */ + dvb->i2c_client_demod = dvb_module_probe("tc90522", "tc90522sat", + &dev->i2c_adap[dev->def_i2c_bus], + 0x15, &tc90522_config); + if (!dvb->i2c_client_demod) + return -ENODEV; + + /* attach tuner */ + qm1d1c0042_config.fe = tc90522_config.fe; + qm1d1c0042_config.lpf = 1; + + dvb->i2c_client_tuner = dvb_module_probe("qm1d1c0042", NULL, + tc90522_config.tuner_i2c, + 0x61, &qm1d1c0042_config); + if (!dvb->i2c_client_tuner) { + dvb_module_release(dvb->i2c_client_demod); + return -ENODEV; + } + + dvb->fe[0] = tc90522_config.fe; + px_bcud_init(dev); + + return 0; +} + +static int em28174_dvb_init_hauppauge_wintv_dualhd_dvb(struct em28xx *dev) +{ + struct em28xx_dvb *dvb = dev->dvb; + struct i2c_adapter *adapter; + struct si2168_config si2168_config = {}; + struct si2157_config si2157_config = {}; + unsigned char addr; + + /* attach demod */ + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &dvb->fe[0]; + si2168_config.ts_mode = SI2168_TS_SERIAL; + si2168_config.spectral_inversion = true; + addr = (dev->ts == PRIMARY_TS) ? 0x64 : 0x67; + + dvb->i2c_client_demod = dvb_module_probe("si2168", NULL, + &dev->i2c_adap[dev->def_i2c_bus], + addr, &si2168_config); + if (!dvb->i2c_client_demod) + return -ENODEV; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = dvb->fe[0]; + si2157_config.if_port = 1; +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + si2157_config.mdev = dev->media_dev; +#endif + addr = (dev->ts == PRIMARY_TS) ? 0x60 : 0x63; + + dvb->i2c_client_tuner = dvb_module_probe("si2157", NULL, + adapter, + addr, &si2157_config); + if (!dvb->i2c_client_tuner) { + dvb_module_release(dvb->i2c_client_demod); + return -ENODEV; + } + + return 0; +} + +static int em28174_dvb_init_hauppauge_wintv_dualhd_01595(struct em28xx *dev) +{ + struct em28xx_dvb *dvb = dev->dvb; + struct i2c_adapter *adapter; + struct lgdt3306a_config lgdt3306a_config = {}; + struct si2157_config si2157_config = {}; + unsigned char addr; + + /* attach demod */ + lgdt3306a_config = hauppauge_01595_lgdt3306a_config; + lgdt3306a_config.fe = &dvb->fe[0]; + lgdt3306a_config.i2c_adapter = &adapter; + addr = (dev->ts == PRIMARY_TS) ? 0x59 : 0x0e; + + dvb->i2c_client_demod = dvb_module_probe("lgdt3306a", NULL, + &dev->i2c_adap[dev->def_i2c_bus], + addr, &lgdt3306a_config); + if (!dvb->i2c_client_demod) + return -ENODEV; + + /* attach tuner */ + si2157_config.fe = dvb->fe[0]; + si2157_config.if_port = 1; + si2157_config.inversion = 1; +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + si2157_config.mdev = dev->media_dev; +#endif + addr = (dev->ts == PRIMARY_TS) ? 0x60 : 0x62; + + dvb->i2c_client_tuner = dvb_module_probe("si2157", NULL, + adapter, + 0x60, &si2157_config); + if (!dvb->i2c_client_tuner) { + dvb_module_release(dvb->i2c_client_demod); + return -ENODEV; + } + + return 0; +} + static int em28xx_dvb_init(struct em28xx *dev) { - int result = 0; + int result = 0, dvb_alt = 0; struct em28xx_dvb *dvb; + struct usb_device *udev; if (dev->is_audio_only) { /* Shouldn't initialize IR for this interface */ @@ -1143,12 +1419,13 @@ static int em28xx_dvb_init(struct em28xx *dev) dev_info(&dev->intf->dev, "Binding DVB extension\n"); - dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); + dvb = kzalloc(sizeof(*dvb), GFP_KERNEL); if (!dvb) return -ENOMEM; dev->dvb = dvb; - dvb->fe[0] = dvb->fe[1] = NULL; + dvb->fe[0] = NULL; + dvb->fe[1] = NULL; /* pre-allocate DVB usb transfer buffers */ if (dev->dvb_xfer_bulk) { @@ -1178,7 +1455,8 @@ static int em28xx_dvb_init(struct em28xx *dev) switch (dev->model) { case EM2874_BOARD_LEADERSHIP_ISDBT: dvb->fe[0] = dvb_attach(s921_attach, - &sharp_isdbt, &dev->i2c_adap[dev->def_i2c_bus]); + &sharp_isdbt, + &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; @@ -1191,8 +1469,8 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->fe[0] = dvb_attach(lgdt330x_attach, - &em2880_lgdt3303_dev, - &dev->i2c_adap[dev->def_i2c_bus]); + &em2880_lgdt3303_dev, + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -1200,8 +1478,8 @@ static int em28xx_dvb_init(struct em28xx *dev) break; case EM2880_BOARD_KWORLD_DVB_310U: dvb->fe[0] = dvb_attach(zl10353_attach, - &em28xx_zl10353_with_xc3028, - &dev->i2c_adap[dev->def_i2c_bus]); + &em28xx_zl10353_with_xc3028, + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -1211,8 +1489,8 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2882_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_EMPIRE_DUAL_TV: dvb->fe[0] = dvb_attach(zl10353_attach, - &em28xx_zl10353_xc3028_no_i2c_gate, - &dev->i2c_adap[dev->def_i2c_bus]); + &em28xx_zl10353_xc3028_no_i2c_gate, + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -1223,16 +1501,17 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2881_BOARD_PINNACLE_HYBRID_PRO: case EM2882_BOARD_DIKOM_DK300: case EM2882_BOARD_KWORLD_VS_DVBT: + /* + * Those boards could have either a zl10353 or a mt352. + * If the chip id isn't for zl10353, try mt352. + */ dvb->fe[0] = dvb_attach(zl10353_attach, - &em28xx_zl10353_xc3028_no_i2c_gate, - &dev->i2c_adap[dev->def_i2c_bus]); - if (dvb->fe[0] == NULL) { - /* This board could have either a zl10353 or a mt352. - If the chip id isn't for zl10353, try mt352 */ + &em28xx_zl10353_xc3028_no_i2c_gate, + &dev->i2c_adap[dev->def_i2c_bus]); + if (!dvb->fe[0]) dvb->fe[0] = dvb_attach(mt352_attach, - &terratec_xs_mt352_cfg, - &dev->i2c_adap[dev->def_i2c_bus]); - } + &terratec_xs_mt352_cfg, + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; @@ -1241,27 +1520,28 @@ static int em28xx_dvb_init(struct em28xx *dev) break; case EM2870_BOARD_TERRATEC_XS_MT2060: dvb->fe[0] = dvb_attach(zl10353_attach, - &em28xx_zl10353_no_i2c_gate_dev, - &dev->i2c_adap[dev->def_i2c_bus]); - if (dvb->fe[0] != NULL) { + &em28xx_zl10353_no_i2c_gate_dev, + &dev->i2c_adap[dev->def_i2c_bus]); + if (dvb->fe[0]) { dvb_attach(mt2060_attach, dvb->fe[0], - &dev->i2c_adap[dev->def_i2c_bus], - &em28xx_mt2060_config, 1220); + &dev->i2c_adap[dev->def_i2c_bus], + &em28xx_mt2060_config, 1220); } break; case EM2870_BOARD_KWORLD_355U: dvb->fe[0] = dvb_attach(zl10353_attach, - &em28xx_zl10353_no_i2c_gate_dev, - &dev->i2c_adap[dev->def_i2c_bus]); - if (dvb->fe[0] != NULL) + &em28xx_zl10353_no_i2c_gate_dev, + &dev->i2c_adap[dev->def_i2c_bus]); + if (dvb->fe[0]) dvb_attach(qt1010_attach, dvb->fe[0], - &dev->i2c_adap[dev->def_i2c_bus], &em28xx_qt1010_config); + &dev->i2c_adap[dev->def_i2c_bus], + &em28xx_qt1010_config); break; case EM2883_BOARD_KWORLD_HYBRID_330U: case EM2882_BOARD_EVGA_INDTUBE: dvb->fe[0] = dvb_attach(s5h1409_attach, - &em28xx_s5h1409_with_xc3028, - &dev->i2c_adap[dev->def_i2c_bus]); + &em28xx_s5h1409_with_xc3028, + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -1269,9 +1549,9 @@ static int em28xx_dvb_init(struct em28xx *dev) break; case EM2882_BOARD_KWORLD_ATSC_315U: dvb->fe[0] = dvb_attach(lgdt330x_attach, - &em2880_lgdt3303_dev, - &dev->i2c_adap[dev->def_i2c_bus]); - if (dvb->fe[0] != NULL) { + &em2880_lgdt3303_dev, + &dev->i2c_adap[dev->def_i2c_bus]); + if (dvb->fe[0]) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x61, TUNER_THOMSON_DTT761X)) { @@ -1293,8 +1573,9 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2870_BOARD_REDDO_DVB_C_USB_BOX: /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ dvb->fe[0] = dvb_attach(tda10023_attach, - &em28xx_tda10023_config, - &dev->i2c_adap[dev->def_i2c_bus], 0x48); + &em28xx_tda10023_config, + &dev->i2c_adap[dev->def_i2c_bus], + 0x48); if (dvb->fe[0]) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], @@ -1306,18 +1587,18 @@ static int em28xx_dvb_init(struct em28xx *dev) break; case EM2870_BOARD_KWORLD_A340: dvb->fe[0] = dvb_attach(lgdt3305_attach, - &em2870_lgdt3304_dev, - &dev->i2c_adap[dev->def_i2c_bus]); + &em2870_lgdt3304_dev, + &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; } if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap[dev->def_i2c_bus], - &kworld_a340_config)) { - dvb_frontend_detach(dvb->fe[0]); - result = -EINVAL; - goto out_free; + &kworld_a340_config)) { + dvb_frontend_detach(dvb->fe[0]); + result = -EINVAL; + goto out_free; } break; case EM28174_BOARD_PCTV_290E: @@ -1335,7 +1616,6 @@ static int em28xx_dvb_init(struct em28xx *dev) 0x60, &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { - dvb_frontend_detach(dvb->fe[0]); result = -EINVAL; goto out_free; @@ -1360,12 +1640,13 @@ static int em28xx_dvb_init(struct em28xx *dev) break; case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: { - struct xc5000_config cfg; + struct xc5000_config cfg = {}; hauppauge_hvr930c_init(dev); dvb->fe[0] = dvb_attach(drxk_attach, - &hauppauge_930c_drxk, &dev->i2c_adap[dev->def_i2c_bus]); + &hauppauge_930c_drxk, + &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; @@ -1377,14 +1658,13 @@ static int em28xx_dvb_init(struct em28xx *dev) dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; /* Attach xc5000 */ - memset(&cfg, 0, sizeof(cfg)); cfg.i2c_address = 0x61; cfg.if_khz = 4000; if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); - if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], - &cfg)) { + if (!dvb_attach(xc5000_attach, dvb->fe[0], + &dev->i2c_adap[dev->def_i2c_bus], &cfg)) { result = -EINVAL; goto out_free; } @@ -1396,7 +1676,8 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2884_BOARD_TERRATEC_H5: terratec_h5_init(dev); - dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap[dev->def_i2c_bus]); + dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, + &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; @@ -1410,7 +1691,8 @@ static int em28xx_dvb_init(struct em28xx *dev) /* Attach tda18271 to DVB-C frontend */ if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); - if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { + if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], + &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { result = -EINVAL; goto out_free; } @@ -1420,72 +1702,23 @@ static int em28xx_dvb_init(struct em28xx *dev) break; case EM2884_BOARD_C3TECH_DIGITAL_DUO: dvb->fe[0] = dvb_attach(mb86a20s_attach, - &c3tech_duo_mb86a20s_config, - &dev->i2c_adap[dev->def_i2c_bus]); - if (dvb->fe[0] != NULL) + &c3tech_duo_mb86a20s_config, + &dev->i2c_adap[dev->def_i2c_bus]); + if (dvb->fe[0]) dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap[dev->def_i2c_bus], &c3tech_duo_tda18271_config); break; - case EM28174_BOARD_PCTV_460E: { - struct i2c_client *client; - struct i2c_board_info board_info; - struct tda10071_platform_data tda10071_pdata = {}; - struct a8293_platform_data a8293_pdata = {}; - - /* attach demod + tuner combo */ - tda10071_pdata.clk = 40444000, /* 40.444 MHz */ - tda10071_pdata.i2c_wr_max = 64, - tda10071_pdata.ts_mode = TDA10071_TS_SERIAL, - tda10071_pdata.pll_multiplier = 20, - tda10071_pdata.tuner_i2c_addr = 0x14, - memset(&board_info, 0, sizeof(board_info)); - strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE); - board_info.addr = 0x55; - board_info.platform_data = &tda10071_pdata; - request_module("tda10071"); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); - if (client == NULL || client->dev.driver == NULL) { - result = -ENODEV; + case EM28174_BOARD_PCTV_460E: + result = em28174_dvb_init_pctv_460e(dev); + if (result) goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client); - dvb->i2c_client_demod = client; - - /* attach SEC */ - a8293_pdata.dvb_frontend = dvb->fe[0]; - memset(&board_info, 0, sizeof(board_info)); - strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); - board_info.addr = 0x08; - board_info.platform_data = &a8293_pdata; - request_module("a8293"); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - dvb->i2c_client_sec = client; break; - } case EM2874_BOARD_DELOCK_61959: case EM2874_BOARD_MAXMEDIA_UB425_TC: /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk, - &dev->i2c_adap[dev->def_i2c_bus]); + &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) { /* disable I2C-gate */ @@ -1507,7 +1740,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk, - &dev->i2c_adap[dev->def_i2c_bus]); + &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) { /* attach tuner */ @@ -1579,13 +1812,7 @@ static int em28xx_dvb_init(struct em28xx *dev) break; case EM2874_BOARD_KWORLD_UB435Q_V3: { - struct i2c_client *client; struct i2c_adapter *adapter = &dev->i2c_adap[dev->def_i2c_bus]; - struct i2c_board_info board_info = { - .type = "tda18212", - .addr = 0x60, - .platform_data = &kworld_ub435q_v3_config, - }; dvb->fe[0] = dvb_attach(lgdt3305_attach, &em2874_lgdt3305_nogate_dev, @@ -1597,28 +1824,23 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach tuner */ kworld_ub435q_v3_config.fe = dvb->fe[0]; - request_module("tda18212"); - client = i2c_new_device(adapter, &board_info); - if (client == NULL || client->dev.driver == NULL) { - dvb_frontend_detach(dvb->fe[0]); - result = -ENODEV; - goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); + dvb->i2c_client_tuner = dvb_module_probe("tda18212", NULL, + adapter, 0x60, + &kworld_ub435q_v3_config); + if (!dvb->i2c_client_tuner) { dvb_frontend_detach(dvb->fe[0]); result = -ENODEV; goto out_free; } - - dvb->i2c_client_tuner = client; break; } case EM2874_BOARD_PCTV_HD_MINI_80E: - dvb->fe[0] = dvb_attach(drx39xxj_attach, &dev->i2c_adap[dev->def_i2c_bus]); - if (dvb->fe[0] != NULL) { - dvb->fe[0] = dvb_attach(tda18271_attach, dvb->fe[0], 0x60, + dvb->fe[0] = dvb_attach(drx39xxj_attach, + &dev->i2c_adap[dev->def_i2c_bus]); + if (dvb->fe[0]) { + dvb->fe[0] = dvb_attach(tda18271_attach, dvb->fe[0], + 0x60, &dev->i2c_adap[dev->def_i2c_bus], &pinnacle_80e_dvb_config); if (!dvb->fe[0]) { @@ -1627,410 +1849,42 @@ static int em28xx_dvb_init(struct em28xx *dev) } } break; - case EM28178_BOARD_PCTV_461E: { - struct i2c_client *client; - struct i2c_adapter *i2c_adapter; - struct i2c_board_info board_info; - struct m88ds3103_platform_data m88ds3103_pdata = {}; - struct ts2020_config ts2020_config = {}; - struct a8293_platform_data a8293_pdata = {}; - - /* attach demod */ - m88ds3103_pdata.clk = 27000000; - m88ds3103_pdata.i2c_wr_max = 33; - m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL; - m88ds3103_pdata.ts_clk = 16000; - m88ds3103_pdata.ts_clk_pol = 1; - m88ds3103_pdata.agc = 0x99; - memset(&board_info, 0, sizeof(board_info)); - strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE); - board_info.addr = 0x68; - board_info.platform_data = &m88ds3103_pdata; - request_module("m88ds3103"); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); - if (client == NULL || client->dev.driver == NULL) { - result = -ENODEV; - goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client); - i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client); - dvb->i2c_client_demod = client; - - /* attach tuner */ - ts2020_config.fe = dvb->fe[0]; - memset(&board_info, 0, sizeof(board_info)); - strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE); - board_info.addr = 0x60; - board_info.platform_data = &ts2020_config; - request_module("ts2020"); - client = i2c_new_device(i2c_adapter, &board_info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - dvb->i2c_client_tuner = client; - /* delegate signal strength measurement to tuner */ - dvb->fe[0]->ops.read_signal_strength = - dvb->fe[0]->ops.tuner_ops.get_rf_strength; - - /* attach SEC */ - a8293_pdata.dvb_frontend = dvb->fe[0]; - memset(&board_info, 0, sizeof(board_info)); - strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); - board_info.addr = 0x08; - board_info.platform_data = &a8293_pdata; - request_module("a8293"); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_tuner->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_tuner); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_tuner->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_tuner); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; + case EM28178_BOARD_PCTV_461E: + result = em28178_dvb_init_pctv_461e(dev); + if (result) goto out_free; - } - dvb->i2c_client_sec = client; break; - } case EM28178_BOARD_PCTV_292E: - { - struct i2c_adapter *adapter; - struct i2c_client *client; - struct i2c_board_info info; - struct si2168_config si2168_config; - struct si2157_config si2157_config; - - /* attach demod */ - memset(&si2168_config, 0, sizeof(si2168_config)); - si2168_config.i2c_adapter = &adapter; - si2168_config.fe = &dvb->fe[0]; - si2168_config.ts_mode = SI2168_TS_PARALLEL; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2168", I2C_NAME_SIZE); - info.addr = 0x64; - info.platform_data = &si2168_config; - request_module(info.type); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); - if (client == NULL || client->dev.driver == NULL) { - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - - dvb->i2c_client_demod = client; - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = dvb->fe[0]; - si2157_config.if_port = 1; -#ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; -#endif - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2157", I2C_NAME_SIZE); - info.addr = 0x60; - info.platform_data = &si2157_config; - request_module(info.type); - client = i2c_new_device(adapter, &info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - - dvb->i2c_client_tuner = client; - dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; - } + result = em28178_dvb_init_pctv_292e(dev); + if (result) + goto out_free; break; case EM28178_BOARD_TERRATEC_T2_STICK_HD: - { - struct i2c_adapter *adapter; - struct i2c_client *client; - struct i2c_board_info info; - struct si2168_config si2168_config; - struct si2157_config si2157_config; - - /* attach demod */ - memset(&si2168_config, 0, sizeof(si2168_config)); - si2168_config.i2c_adapter = &adapter; - si2168_config.fe = &dvb->fe[0]; - si2168_config.ts_mode = SI2168_TS_PARALLEL; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2168", I2C_NAME_SIZE); - info.addr = 0x64; - info.platform_data = &si2168_config; - request_module(info.type); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); - if (client == NULL || client->dev.driver == NULL) { - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - - dvb->i2c_client_demod = client; - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = dvb->fe[0]; - si2157_config.if_port = 0; -#ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; -#endif - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2146", I2C_NAME_SIZE); - info.addr = 0x60; - info.platform_data = &si2157_config; - request_module("si2157"); - client = i2c_new_device(adapter, &info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - - dvb->i2c_client_tuner = client; - } + result = em28178_dvb_init_terratec_t2_stick_hd(dev); + if (result) + goto out_free; break; - case EM28178_BOARD_PLEX_PX_BCUD: - { - struct i2c_client *client; - struct i2c_board_info info; - struct tc90522_config tc90522_config; - struct qm1d1c0042_config qm1d1c0042_config; - - /* attach demod */ - memset(&tc90522_config, 0, sizeof(tc90522_config)); - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE); - info.addr = 0x15; - info.platform_data = &tc90522_config; - request_module("tc90522"); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); - if (client == NULL || client->dev.driver == NULL) { - result = -ENODEV; - goto out_free; - } - dvb->i2c_client_demod = client; - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - - /* attach tuner */ - memset(&qm1d1c0042_config, 0, - sizeof(qm1d1c0042_config)); - qm1d1c0042_config.fe = tc90522_config.fe; - qm1d1c0042_config.lpf = 1; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE); - info.addr = 0x61; - info.platform_data = &qm1d1c0042_config; - request_module(info.type); - client = i2c_new_device(tc90522_config.tuner_i2c, - &info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - dvb->i2c_client_tuner = client; - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - dvb->fe[0] = tc90522_config.fe; - px_bcud_init(dev); - } + result = em28178_dvb_init_plex_px_bcud(dev); + if (result) + goto out_free; break; case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB: - { - struct i2c_adapter *adapter; - struct i2c_client *client; - struct i2c_board_info info; - struct si2168_config si2168_config; - struct si2157_config si2157_config; - - /* attach demod */ - memset(&si2168_config, 0, sizeof(si2168_config)); - si2168_config.i2c_adapter = &adapter; - si2168_config.fe = &dvb->fe[0]; - si2168_config.ts_mode = SI2168_TS_SERIAL; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2168", I2C_NAME_SIZE); - info.addr = 0x64; - info.platform_data = &si2168_config; - request_module(info.type); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); - if (client == NULL || client->dev.driver == NULL) { - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - - dvb->i2c_client_demod = client; - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = dvb->fe[0]; - si2157_config.if_port = 1; -#ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; -#endif - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2157", I2C_NAME_SIZE); - info.addr = 0x60; - info.platform_data = &si2157_config; - request_module(info.type); - client = i2c_new_device(adapter, &info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - - dvb->i2c_client_tuner = client; - - } + result = em28174_dvb_init_hauppauge_wintv_dualhd_dvb(dev); + if (result) + goto out_free; break; case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595: - { - struct i2c_adapter *adapter; - struct i2c_client *client; - struct i2c_board_info info = {}; - struct lgdt3306a_config lgdt3306a_config; - struct si2157_config si2157_config = {}; - - /* attach demod */ - lgdt3306a_config = hauppauge_01595_lgdt3306a_config; - lgdt3306a_config.fe = &dvb->fe[0]; - lgdt3306a_config.i2c_adapter = &adapter; - strlcpy(info.type, "lgdt3306a", sizeof(info.type)); - info.addr = 0x59; - info.platform_data = &lgdt3306a_config; - request_module(info.type); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], - &info); - if (client == NULL || client->dev.driver == NULL) { - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - - dvb->i2c_client_demod = client; - - /* attach tuner */ - si2157_config.fe = dvb->fe[0]; - si2157_config.if_port = 1; - si2157_config.inversion = 1; -#ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; -#endif - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2157", sizeof(info.type)); - info.addr = 0x60; - info.platform_data = &si2157_config; - request_module(info.type); - - client = i2c_new_device(adapter, &info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod); - result = -ENODEV; - goto out_free; - } - - dvb->i2c_client_tuner = client; - } + result = em28174_dvb_init_hauppauge_wintv_dualhd_01595(dev); + if (result) + goto out_free; break; default: dev_err(&dev->intf->dev, "The frontend of your DVB/ATSC card isn't supported yet\n"); break; } - if (NULL == dvb->fe[0]) { + if (!dvb->fe[0]) { dev_err(&dev->intf->dev, "frontend initialization failed\n"); result = -EINVAL; goto out_free; @@ -2046,6 +1900,14 @@ static int em28xx_dvb_init(struct em28xx *dev) if (result < 0) goto out_free; + if (dev->dvb_xfer_bulk) { + dvb_alt = 0; + } else { /* isoc */ + dvb_alt = dev->dvb_alt_isoc; + } + + udev = interface_to_usbdev(dev->intf); + usb_set_interface(udev, dev->ifnum, dvb_alt); dev_info(&dev->intf->dev, "DVB extension successfully initialized\n"); kref_get(&dev->ref); @@ -2071,7 +1933,6 @@ static inline void prevent_sleep(struct dvb_frontend_ops *ops) static int em28xx_dvb_fini(struct em28xx *dev) { struct em28xx_dvb *dvb; - struct i2c_client *client; if (dev->is_audio_only) { /* Shouldn't initialize IR for this interface */ @@ -2093,8 +1954,10 @@ static int em28xx_dvb_fini(struct em28xx *dev) em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE); if (dev->disconnected) { - /* We cannot tell the device to sleep - * once it has been unplugged. */ + /* + * We cannot tell the device to sleep + * once it has been unplugged. + */ if (dvb->fe[0]) { prevent_sleep(&dvb->fe[0]->ops); dvb->fe[0]->exit = DVB_FE_DEVICE_REMOVED; @@ -2107,26 +1970,10 @@ static int em28xx_dvb_fini(struct em28xx *dev) em28xx_unregister_dvb(dvb); - /* remove I2C SEC */ - client = dvb->i2c_client_sec; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - } - - /* remove I2C tuner */ - client = dvb->i2c_client_tuner; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - } - - /* remove I2C demod */ - client = dvb->i2c_client_demod; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - } + /* release I2C module bindings */ + dvb_module_release(dvb->i2c_client_sec); + dvb_module_release(dvb->i2c_client_tuner); + dvb_module_release(dvb->i2c_client_demod); kfree(dvb); dev->dvb = NULL; diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 9bf49d666e5a..9151bccd859a 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -1,26 +1,22 @@ -/* - em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - - Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> - Markus Rechberger <mrechberger@gmail.com> - Mauro Carvalho Chehab <mchehab@infradead.org> - Sascha Sommer <saschasommer@freenet.de> - Copyright (C) 2013 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices +// +// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> +// Markus Rechberger <mrechberger@gmail.com> +// Mauro Carvalho Chehab <mchehab@infradead.org> +// Sascha Sommer <saschasommer@freenet.de> +// Copyright (C) 2013 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" @@ -50,6 +46,35 @@ MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I "i2c: %s: " fmt, __func__, ## arg); \ } while (0) +/* + * Time in msecs to wait for i2c xfers to finish. + * 35ms is the maximum time a SMBUS device could wait when + * clock stretching is used. As the transfer itself will take + * some time to happen, set it to 35 ms. + * + * Ok, I2C doesn't specify any limit. So, eventually, we may need + * to increase this timeout. + */ +#define EM28XX_I2C_XFER_TIMEOUT 35 /* ms */ + +static int em28xx_i2c_timeout(struct em28xx *dev) +{ + int time = EM28XX_I2C_XFER_TIMEOUT; + + switch (dev->i2c_speed & 0x03) { + case EM28XX_I2C_FREQ_25_KHZ: + time += 4; /* Assume 4 ms for transfers */ + break; + case EM28XX_I2C_FREQ_100_KHZ: + case EM28XX_I2C_FREQ_400_KHZ: + time += 1; /* Assume 1 ms for transfers */ + break; + default: /* EM28XX_I2C_FREQ_1_5_MHZ */ + break; + } + + return msecs_to_jiffies(time); +} /* * em2800_i2c_send_bytes() @@ -57,14 +82,13 @@ MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I */ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) { - unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); + unsigned long timeout = jiffies + em28xx_i2c_timeout(dev); int ret; u8 b2[6]; if (len < 1 || len > 4) return -EOPNOTSUPP; - BUG_ON(len < 1 || len > 4); b2[5] = 0x80 + len - 1; b2[4] = addr; b2[3] = buf[0]; @@ -98,7 +122,7 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) ret); return ret; } - msleep(5); + usleep_range(5000, 6000); } dprintk(0, "write to i2c device at 0x%x timed out\n", addr); return -ETIMEDOUT; @@ -110,7 +134,7 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) */ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) { - unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); + unsigned long timeout = jiffies + em28xx_i2c_timeout(dev); u8 buf2[4]; int ret; int i; @@ -145,14 +169,13 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) ret); return ret; } - msleep(5); + usleep_range(5000, 6000); } - if (ret != 0x84 + len - 1) { + if (ret != 0x84 + len - 1) dprintk(0, "read from i2c device at 0x%x timed out\n", addr); - } /* get the received message */ - ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); + ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4 - len, buf2, len); if (ret != len) { dev_warn(&dev->intf->dev, "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", @@ -186,7 +209,7 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr) static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len, int stop) { - unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); + unsigned long timeout = jiffies + em28xx_i2c_timeout(dev); int ret; if (len < 1 || len > 64) @@ -204,12 +227,11 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, "writing to i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; - } else { - dev_warn(&dev->intf->dev, - "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", - len, addr, ret); - return -EIO; } + dev_warn(&dev->intf->dev, + "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", + len, addr, ret); + return -EIO; } /* wait for completion */ @@ -228,7 +250,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ret); return ret; } - msleep(5); + usleep_range(5000, 6000); /* * NOTE: do we really have to wait for success ? * Never seen anything else than 0x00 or 0x10 @@ -351,12 +373,12 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, "writing to i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; - } else { - dev_warn(&dev->intf->dev, - "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", - len, addr, ret); - return -EIO; } + + dev_warn(&dev->intf->dev, + "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", + len, addr, ret); + return -EIO; } /* Check success */ ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000); @@ -366,7 +388,8 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, */ if (!ret) return len; - else if (ret > 0) { + + if (ret > 0) { dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } @@ -420,7 +443,8 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, */ if (!ret) return len; - else if (ret > 0) { + + if (ret > 0) { dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } @@ -508,13 +532,15 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, { struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; struct em28xx *dev = i2c_bus->dev; - unsigned bus = i2c_bus->bus; + unsigned int bus = i2c_bus->bus; int addr, rc, i; u8 reg; - /* prevent i2c xfer attempts after device is disconnected - some fe's try to do i2c writes/reads from their release - interfaces when called in disconnect path */ + /* + * prevent i2c xfer attempts after device is disconnected + * some fe's try to do i2c writes/reads from their release + * interfaces when called in disconnect path + */ if (dev->disconnected) return -ENODEV; @@ -597,12 +623,13 @@ static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) if (len == length) { c = (char)len; len = -1; - } else + } else { c = *buf++; + } l = (l << 8) | c; len++; if ((len & (32 / 8 - 1)) == 0) - hash = ((hash^l) * 0x9e370001UL); + hash = ((hash ^ l) * 0x9e370001UL); } while (len); return (hash >> (32 - bits)) & 0xffffffffUL; @@ -612,7 +639,7 @@ static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) * Helper function to read data blocks from i2c clients with 8 or 16 bit * address width, 8 bit register width and auto incrementation been activated */ -static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, +static int em28xx_i2c_read_block(struct em28xx *dev, unsigned int bus, u16 addr, bool addr_w16, u16 len, u8 *data) { int remain = len, rsize, rsize_max, ret; @@ -624,7 +651,8 @@ static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, /* Select address */ buf[0] = addr >> 8; buf[1] = addr & 0xff; - ret = i2c_master_send(&dev->i2c_client[bus], buf + !addr_w16, 1 + addr_w16); + ret = i2c_master_send(&dev->i2c_client[bus], + buf + !addr_w16, 1 + addr_w16); if (ret < 0) return ret; /* Read data */ @@ -649,7 +677,7 @@ static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, return len; } -static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, +static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned int bus, u8 **eedata, u16 *eedata_len) { const u16 len = 256; @@ -677,7 +705,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, } data = kzalloc(len, GFP_KERNEL); - if (data == NULL) + if (!data) return -ENOMEM; /* Read EEPROM content */ @@ -710,8 +738,8 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ dev_info(&dev->intf->dev, - "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", - data[0], data[1], data[2], data[3], dev->hash); + "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n", + data, dev->hash); dev_info(&dev->intf->dev, "EEPROM info:\n"); dev_info(&dev->intf->dev, @@ -769,15 +797,18 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, return 0; } - /* TODO: decrypt eeprom data for camera bridges (em25xx, em276x+) */ + /* + * TODO: decrypt eeprom data for camera bridges + * (em25xx, em276x+) + */ } else if (!dev->eeprom_addrwidth_16bit && data[0] == 0x1a && data[1] == 0xeb && data[2] == 0x67 && data[3] == 0x95) { dev->hash = em28xx_hash_mem(data, len, 32); dev_info(&dev->intf->dev, - "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", - data[0], data[1], data[2], data[3], dev->hash); + "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n", + data, dev->hash); dev_info(&dev->intf->dev, "EEPROM info:\n"); } else { @@ -859,8 +890,8 @@ static u32 functionality(struct i2c_adapter *i2c_adap) { struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; - if ((i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) || - (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)) { + if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX || + i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) { return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) & @@ -893,7 +924,7 @@ static const struct i2c_client em28xx_client_template = { * incomplete list of known devices */ static char *i2c_devs[128] = { - [0x1c >> 1] = "lgdt330x", + [0x1c >> 1] = "lgdt330x", [0x3e >> 1] = "remote IR sensor", [0x4a >> 1] = "saa7113h", [0x52 >> 1] = "drxk", @@ -916,7 +947,7 @@ static char *i2c_devs[128] = { * do_i2c_scan() * check i2c address range for devices */ -void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) +void em28xx_do_i2c_scan(struct em28xx *dev, unsigned int bus) { u8 i2c_devicelist[128]; unsigned char buf; @@ -944,13 +975,14 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) * em28xx_i2c_register() * register i2c bus */ -int em28xx_i2c_register(struct em28xx *dev, unsigned bus, +int em28xx_i2c_register(struct em28xx *dev, unsigned int bus, enum em28xx_i2c_algo_type algo_type) { int retval; - BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); - BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); + if (WARN_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg || + !dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req)) + return -ENODEV; if (bus >= NUM_I2C_BUSES) return -ENODEV; @@ -977,8 +1009,9 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, /* Up to now, all eeproms are at bus 0 */ if (!bus) { - retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); - if ((retval < 0) && (retval != -ENODEV)) { + retval = em28xx_i2c_eeprom(dev, bus, + &dev->eedata, &dev->eedata_len); + if (retval < 0 && retval != -ENODEV) { dev_err(&dev->intf->dev, "%s: em28xx_i2_eeprom failed! retval [%d]\n", __func__, retval); @@ -995,7 +1028,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, * em28xx_i2c_unregister() * unregister i2c_bus */ -int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus) +int em28xx_i2c_unregister(struct em28xx *dev, unsigned int bus) { if (bus >= NUM_I2C_BUSES) return -ENODEV; diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 046223de1e91..2dc1be00b8b8 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -1,25 +1,21 @@ -/* - handle em28xx IR remotes via linux kernel input layer. - - Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> - Markus Rechberger <mrechberger@gmail.com> - Mauro Carvalho Chehab <mchehab@infradead.org> - Sascha Sommer <saschasommer@freenet.de> - - 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// handle em28xx IR remotes via linux kernel input layer. +// +// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> +// Markus Rechberger <mrechberger@gmail.com> +// Mauro Carvalho Chehab <mchehab@infradead.org> +// Sascha Sommer <saschasommer@freenet.de> +// +// 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" @@ -41,15 +37,15 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); #define MODULE_NAME "em28xx" -#define dprintk( fmt, arg...) do { \ +#define dprintk(fmt, arg...) do { \ if (ir_debug) \ dev_printk(KERN_DEBUG, &ir->dev->intf->dev, \ "input: %s: " fmt, __func__, ## arg); \ } while (0) -/********************************************************** - Polling structure used by em28xx IR's - **********************************************************/ +/* + * Polling structure used by em28xx IR's + */ struct em28xx_ir_poll_result { unsigned int toggle_bit:1; @@ -76,24 +72,31 @@ struct em28xx_IR { int (*get_key_i2c)(struct i2c_client *ir, enum rc_proto *protocol, u32 *scancode); - int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); + int (*get_key)(struct em28xx_IR *ir, struct em28xx_ir_poll_result *r); }; -/********************************************************** - I2C IR based get keycodes - should be used with ir-kbd-i2c - **********************************************************/ +/* + * I2C IR based get keycodes - should be used with ir-kbd-i2c + */ static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, enum rc_proto *protocol, u32 *scancode) { + int rc; unsigned char b; /* poll IR chip */ - if (1 != i2c_master_recv(i2c_dev, &b, 1)) + rc = i2c_master_recv(i2c_dev, &b, 1); + if (rc != 1) { + if (rc < 0) + return rc; return -EIO; + } - /* it seems that 0xFE indicates that a button is still hold - down, while 0xff indicates that no button is hold down. */ + /* + * it seems that 0xFE indicates that a button is still hold + * down, while 0xff indicates that no button is hold down. + */ if (b == 0xff) return 0; @@ -145,7 +148,7 @@ static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev, /* poll IR chip */ - if (3 != i2c_master_recv(i2c_dev, buf, 3)) + if (i2c_master_recv(i2c_dev, buf, 3) != 3) return -EIO; if (buf[0] != 0x00) @@ -162,18 +165,28 @@ static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev, { unsigned char subaddr, keydetect, key; - struct i2c_msg msg[] = { { .addr = i2c_dev->addr, .flags = 0, .buf = &subaddr, .len = 1}, - { .addr = i2c_dev->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} }; + struct i2c_msg msg[] = { + { + .addr = i2c_dev->addr, + .flags = 0, + .buf = &subaddr, .len = 1 + }, { + .addr = i2c_dev->addr, + .flags = I2C_M_RD, + .buf = &keydetect, + .len = 1 + } + }; subaddr = 0x10; - if (2 != i2c_transfer(i2c_dev->adapter, msg, 2)) + if (i2c_transfer(i2c_dev->adapter, msg, 2) != 2) return -EIO; if (keydetect == 0x00) return 0; subaddr = 0x00; msg[1].buf = &key; - if (2 != i2c_transfer(i2c_dev->adapter, msg, 2)) + if (i2c_transfer(i2c_dev->adapter, msg, 2) != 2) return -EIO; if (key == 0x00) return 0; @@ -183,9 +196,9 @@ static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev, return 1; } -/********************************************************** - Poll based get keycode functions - **********************************************************/ +/* + * Poll based get keycode functions + */ /* This is for the em2860/em2880 */ static int default_polling_getkey(struct em28xx_IR *ir, @@ -195,8 +208,9 @@ static int default_polling_getkey(struct em28xx_IR *ir, int rc; u8 msg[3] = { 0, 0, 0 }; - /* Read key toggle, brand, and key code - on registers 0x45, 0x46 and 0x47 + /* + * Read key toggle, brand, and key code + * on registers 0x45, 0x46 and 0x47 */ rc = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R45_IR, msg, sizeof(msg)); @@ -237,8 +251,9 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, int rc; u8 msg[5] = { 0, 0, 0, 0, 0 }; - /* Read key toggle, brand, and key code - on registers 0x51-55 + /* + * Read key toggle, brand, and key code + * on registers 0x51-55 */ rc = dev->em28xx_read_reg_req_len(dev, 0, EM2874_R51_IR, msg, sizeof(msg)); @@ -294,9 +309,9 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, return 0; } -/********************************************************** - Polling code for em28xx - **********************************************************/ +/* + * Polling code for em28xx + */ static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir) { @@ -347,11 +362,14 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) if (ir->dev->chip_id == CHIP_ID_EM2874 || ir->dev->chip_id == CHIP_ID_EM2884) - /* The em2874 clears the readcount field every time the - register is read. The em2860/2880 datasheet says that it - is supposed to clear the readcount, but it doesn't. So with - the em2874, we are looking for a non-zero read count as - opposed to a readcount that is incrementing */ + /* + * The em2874 clears the readcount field every time the + * register is read. The em2860/2880 datasheet says + * that it is supposed to clear the readcount, but it + * doesn't. So with the em2874, we are looking for a + * non-zero read count as opposed to a readcount + * that is incrementing + */ ir->last_readcount = 0; else ir->last_readcount = poll_result.read_count; @@ -476,15 +494,18 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_proto) static int em28xx_probe_i2c_ir(struct em28xx *dev) { int i = 0; - /* Leadtek winfast tv USBII deluxe can find a non working IR-device */ - /* at address 0x18, so if that address is needed for another board in */ - /* the future, please put it after 0x1f. */ + /* + * Leadtek winfast tv USBII deluxe can find a non working IR-device + * at address 0x18, so if that address is needed for another board in + * the future, please put it after 0x1f. + */ const unsigned short addr_list[] = { 0x1f, 0x30, 0x47, I2C_CLIENT_END }; while (addr_list[i] != I2C_CLIENT_END) { - if (i2c_probe_func_quick_read(&dev->i2c_adap[dev->def_i2c_bus], addr_list[i]) == 1) + if (i2c_probe_func_quick_read(&dev->i2c_adap[dev->def_i2c_bus], + addr_list[i]) == 1) return addr_list[i]; i++; } @@ -492,9 +513,9 @@ static int em28xx_probe_i2c_ir(struct em28xx *dev) return -ENODEV; } -/********************************************************** - Handle buttons - **********************************************************/ +/* + * Handle buttons + */ static void em28xx_query_buttons(struct work_struct *work) { @@ -515,7 +536,10 @@ static void em28xx_query_buttons(struct work_struct *work) j = 0; while (dev->board.buttons[j].role >= 0 && dev->board.buttons[j].role < EM28XX_NUM_BUTTON_ROLES) { - struct em28xx_button *button = &dev->board.buttons[j]; + const struct em28xx_button *button; + + button = &dev->board.buttons[j]; + /* Check if button uses the current address */ if (button->reg_r != dev->button_polling_addresses[i]) { j++; @@ -618,7 +642,8 @@ static void em28xx_init_buttons(struct em28xx *dev) dev->button_polling_interval = EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL; while (dev->board.buttons[i].role >= 0 && dev->board.buttons[i].role < EM28XX_NUM_BUTTON_ROLES) { - struct em28xx_button *button = &dev->board.buttons[i]; + const struct em28xx_button *button = &dev->board.buttons[i]; + /* Check if polling address is already on the list */ addr_new = true; for (j = 0; j < dev->num_button_polling_addresses; j++) { @@ -649,6 +674,7 @@ static void em28xx_init_buttons(struct em28xx *dev) /* Add read address to list of polling addresses */ if (addr_new) { unsigned int index = dev->num_button_polling_addresses; + dev->button_polling_addresses[index] = button->reg_r; dev->num_button_polling_addresses++; } @@ -677,7 +703,7 @@ static void em28xx_shutdown_buttons(struct em28xx *dev) /* Clear polling addresses list */ dev->num_button_polling_addresses = 0; /* Deregister input devices */ - if (dev->sbutton_input_dev != NULL) { + if (dev->sbutton_input_dev) { dev_info(&dev->intf->dev, "Deregistering snapshot button\n"); input_unregister_device(dev->sbutton_input_dev); dev->sbutton_input_dev = NULL; @@ -714,7 +740,7 @@ static int em28xx_ir_init(struct em28xx *dev) } } - if (dev->board.ir_codes == NULL && !dev->board.has_ir_i2c) { + if (!dev->board.ir_codes && !dev->board.has_ir_i2c) { /* No remote control support */ dev_warn(&dev->intf->dev, "Remote control support is not available for this card.\n"); @@ -764,7 +790,7 @@ static int em28xx_ir_init(struct em28xx *dev) goto error; } - ir->i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + ir->i2c_client = kzalloc(sizeof(*ir->i2c_client), GFP_KERNEL); if (!ir->i2c_client) goto error; ir->i2c_client->adapter = &ir->dev->i2c_adap[dev->def_i2c_bus]; @@ -881,9 +907,11 @@ static int em28xx_ir_suspend(struct em28xx *dev) if (ir) cancel_delayed_work_sync(&ir->work); cancel_delayed_work_sync(&dev->buttons_query_work); - /* is canceling delayed work sufficient or does the rc event - kthread needs stopping? kthread is stopped in - ir_raw_event_unregister() */ + /* + * is canceling delayed work sufficient or does the rc event + * kthread needs stopping? kthread is stopped in + * ir_raw_event_unregister() + */ return 0; } @@ -895,8 +923,10 @@ static int em28xx_ir_resume(struct em28xx *dev) return 0; dev_info(&dev->intf->dev, "Resuming input extension\n"); - /* if suspend calls ir_raw_event_unregister(), the should call - ir_raw_event_register() */ + /* + * if suspend calls ir_raw_event_unregister(), the should call + * ir_raw_event_register() + */ if (ir) schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); if (dev->num_button_polling_addresses) @@ -924,7 +954,7 @@ static void __exit em28xx_rc_unregister(void) em28xx_unregister_extension(&rc_ops); } -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_DESCRIPTION(DRIVER_DESC " - input interface"); MODULE_VERSION(EM28XX_VERSION); diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h index 9e5cdfb25a73..f53afe18e92d 100644 --- a/drivers/media/usb/em28xx/em28xx-reg.h +++ b/drivers/media/usb/em28xx/em28xx-reg.h @@ -1,17 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#define EM_GPIO_0 (1 << 0) -#define EM_GPIO_1 (1 << 1) -#define EM_GPIO_2 (1 << 2) -#define EM_GPIO_3 (1 << 3) -#define EM_GPIO_4 (1 << 4) -#define EM_GPIO_5 (1 << 5) -#define EM_GPIO_6 (1 << 6) -#define EM_GPIO_7 (1 << 7) - -#define EM_GPO_0 (1 << 0) -#define EM_GPO_1 (1 << 1) -#define EM_GPO_2 (1 << 2) -#define EM_GPO_3 (1 << 3) + +/* + * em28xx-reg.h - Register definitions for em28xx driver + */ + +#define EM_GPIO_0 ((unsigned char)BIT(0)) +#define EM_GPIO_1 ((unsigned char)BIT(1)) +#define EM_GPIO_2 ((unsigned char)BIT(2)) +#define EM_GPIO_3 ((unsigned char)BIT(3)) +#define EM_GPIO_4 ((unsigned char)BIT(4)) +#define EM_GPIO_5 ((unsigned char)BIT(5)) +#define EM_GPIO_6 ((unsigned char)BIT(6)) +#define EM_GPIO_7 ((unsigned char)BIT(7)) + +#define EM_GPO_0 ((unsigned char)BIT(0)) +#define EM_GPO_1 ((unsigned char)BIT(1)) +#define EM_GPO_2 ((unsigned char)BIT(2)) +#define EM_GPO_3 ((unsigned char)BIT(3)) /* em28xx endpoints */ /* 0x82: (always ?) analog */ @@ -203,10 +208,11 @@ #define EM28XX_R43_AC97BUSY 0x43 #define EM28XX_R45_IR 0x45 - /* 0x45 bit 7 - parity bit - bits 6-0 - count - 0x46 IR brand - 0x47 IR data + /* + * 0x45 bit 7 - parity bit + * bits 6-0 - count + * 0x46 IR brand + * 0x47 IR data */ /* em2874 registers */ @@ -249,12 +255,12 @@ #define EM2874_IR_RC6_MODE_6A 0x0b /* em2874 Transport Stream Enable Register (0x5f) */ -#define EM2874_TS1_CAPTURE_ENABLE (1 << 0) -#define EM2874_TS1_FILTER_ENABLE (1 << 1) -#define EM2874_TS1_NULL_DISCARD (1 << 2) -#define EM2874_TS2_CAPTURE_ENABLE (1 << 4) -#define EM2874_TS2_FILTER_ENABLE (1 << 5) -#define EM2874_TS2_NULL_DISCARD (1 << 6) +#define EM2874_TS1_CAPTURE_ENABLE ((unsigned char)BIT(0)) +#define EM2874_TS1_FILTER_ENABLE ((unsigned char)BIT(1)) +#define EM2874_TS1_NULL_DISCARD ((unsigned char)BIT(2)) +#define EM2874_TS2_CAPTURE_ENABLE ((unsigned char)BIT(4)) +#define EM2874_TS2_FILTER_ENABLE ((unsigned char)BIT(5)) +#define EM2874_TS2_NULL_DISCARD ((unsigned char)BIT(6)) /* register settings */ #define EM2800_AUDIO_SRC_TUNER 0x0d diff --git a/drivers/media/usb/em28xx/em28xx-v4l.h b/drivers/media/usb/em28xx/em28xx-v4l.h index 9c411aac3878..1788dbf9024a 100644 --- a/drivers/media/usb/em28xx/em28xx-v4l.h +++ b/drivers/media/usb/em28xx/em28xx-v4l.h @@ -1,17 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB - video capture devices - - Copyright (C) 2013-2014 Mauro Carvalho Chehab <m.chehab@samsung.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 version 2 of the License. - - 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. + * em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB + * video capture devices + * + * Copyright (C) 2013-2014 Mauro Carvalho Chehab <m.chehab@samsung.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 version 2 of the License. + * + * 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. */ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count); diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index f5123651ef30..63c48361d3f2 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c @@ -1,25 +1,20 @@ -/* - em28xx-vbi.c - VBI driver for em28xx - - Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> - - This work was sponsored by EyeMagnet Limited. - - 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// em28xx-vbi.c - VBI driver for em28xx +// +// Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> +// +// This work was sponsored by EyeMagnet Limited. +// +// 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" diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index a2ba2d905952..d70ee13cc52e 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1,30 +1,26 @@ -/* - em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB - video capture devices - - Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> - Markus Rechberger <mrechberger@gmail.com> - Mauro Carvalho Chehab <mchehab@infradead.org> - Sascha Sommer <saschasommer@freenet.de> - Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> - - Some parts based on SN9C10x PC Camera Controllers GPL driver made - by Luca Risolia <luca.risolia@studio.unibo.it> - - 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB +// video capture devices +// +// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> +// Markus Rechberger <mrechberger@gmail.com> +// Mauro Carvalho Chehab <mchehab@infradead.org> +// Sascha Sommer <saschasommer@freenet.de> +// Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> +// +// Some parts based on SN9C10x PC Camera Controllers GPL driver made +// by Luca Risolia <luca.risolia@studio.unibo.it> +// +// 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" @@ -77,7 +73,7 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_VERSION(EM28XX_VERSION); #define EM25XX_FRMDATAHDR_BYTE1 0x02 @@ -148,7 +144,7 @@ static inline unsigned int norm_maxw(struct em28xx *dev) { struct em28xx_v4l2 *v4l2 = dev->v4l2; - if (dev->board.is_webcam) + if (dev->is_webcam) return v4l2->sensor_xres; if (dev->board.max_range_640_480) @@ -161,7 +157,7 @@ static inline unsigned int norm_maxh(struct em28xx *dev) { struct em28xx_v4l2 *v4l2 = dev->v4l2; - if (dev->board.is_webcam) + if (dev->is_webcam) return v4l2->sensor_yres; if (dev->board.max_range_640_480) @@ -176,7 +172,7 @@ static int em28xx_vbi_supported(struct em28xx *dev) if (disable_vbi == 1) return 0; - if (dev->board.is_webcam) + if (dev->is_webcam) return 0; /* FIXME: check subdevices for VBI support */ @@ -250,7 +246,8 @@ static int em28xx_set_outfmt(struct em28xx *dev) if (em28xx_vbi_supported(dev) == 1) { vinctrl |= EM28XX_VINCTRL_VBI_RAW; em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); - em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, v4l2->vbi_width/4); + em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, + v4l2->vbi_width / 4); em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, v4l2->vbi_height); if (v4l2->norm & V4L2_STD_525_60) { /* NTSC */ @@ -320,8 +317,10 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) buf[0] = v; buf[1] = v >> 8; em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); - /* it seems that both H and V scalers must be active - to work correctly */ + /* + * it seems that both H and V scalers must be active + * to work correctly + */ mode = (h || v) ? 0x30 : 0x00; } return em28xx_write_reg(dev, EM28XX_R26_COMPR, mode); @@ -345,13 +344,15 @@ static int em28xx_resolution_set(struct em28xx *dev) em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); - /* If we don't set the start position to 2 in VBI mode, we end up - with line 20/21 being YUYV encoded instead of being in 8-bit - greyscale. The core of the issue is that line 21 (and line 23 for - PAL WSS) are inside of active video region, and as a result they - get the pixelformatting associated with that area. So by cropping - it out, we end up with the same format as the rest of the VBI - region */ + /* + * If we don't set the start position to 2 in VBI mode, we end up + * with line 20/21 being YUYV encoded instead of being in 8-bit + * greyscale. The core of the issue is that line 21 (and line 23 for + * PAL WSS) are inside of active video region, and as a result they + * get the pixelformatting associated with that area. So by cropping + * it out, we end up with the same format as the rest of the VBI + * region + */ if (em28xx_vbi_supported(dev) == 1) em28xx_capture_area_set(dev, 0, 2, width, height); else @@ -365,14 +366,16 @@ static int em28xx_set_alternate(struct em28xx *dev) { struct em28xx_v4l2 *v4l2 = dev->v4l2; struct usb_device *udev = interface_to_usbdev(dev->intf); - int errCode; + int err; int i; unsigned int min_pkt_size = v4l2->width * 2 + 4; - /* NOTE: for isoc transfers, only alt settings > 0 are allowed - bulk transfers seem to work only with alt=0 ! */ + /* + * NOTE: for isoc transfers, only alt settings > 0 are allowed + * bulk transfers seem to work only with alt=0 ! + */ dev->alt = 0; - if ((alt > 0) && (alt < dev->num_alt)) { + if (alt > 0 && alt < dev->num_alt) { em28xx_videodbg("alternate forced to %d\n", dev->alt); dev->alt = alt; goto set_alt; @@ -380,9 +383,10 @@ static int em28xx_set_alternate(struct em28xx *dev) if (dev->analog_xfer_bulk) goto set_alt; - /* When image size is bigger than a certain value, - the frame size should be increased, otherwise, only - green screen will be received. + /* + * When image size is bigger than a certain value, + * the frame size should be increased, otherwise, only + * green screen will be received. */ if (v4l2->width * 2 * v4l2->height > 720 * 240 * 2) min_pkt_size *= 2; @@ -392,18 +396,22 @@ static int em28xx_set_alternate(struct em28xx *dev) if (dev->alt_max_pkt_size_isoc[i] >= min_pkt_size) { dev->alt = i; break; - /* otherwise make sure that we end up with the maximum bandwidth - because the min_pkt_size equation might be wrong... - */ + /* + * otherwise make sure that we end up with the maximum + * bandwidth because the min_pkt_size equation might be wrong. + * + */ } else if (dev->alt_max_pkt_size_isoc[i] > dev->alt_max_pkt_size_isoc[dev->alt]) dev->alt = i; } set_alt: - /* NOTE: for bulk transfers, we need to call usb_set_interface() + /* + * NOTE: for bulk transfers, we need to call usb_set_interface() * even if the previous settings were the same. Otherwise streaming - * fails with all urbs having status = -EOVERFLOW ! */ + * fails with all urbs having status = -EOVERFLOW ! + */ if (dev->analog_xfer_bulk) { dev->max_pkt_size = 512; /* USB 2.0 spec */ dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER; @@ -416,19 +424,19 @@ set_alt: } em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt, dev->max_pkt_size); - errCode = usb_set_interface(udev, dev->ifnum, dev->alt); - if (errCode < 0) { + err = usb_set_interface(udev, dev->ifnum, dev->alt); + if (err < 0) { dev_err(&dev->intf->dev, "cannot change alternate number to %d (error=%i)\n", - dev->alt, errCode); - return errCode; + dev->alt, err); + return err; } return 0; } -/* ------------------------------------------------------------------ - DMA and thread functions - ------------------------------------------------------------------*/ +/* + * DMA and thread functions + */ /* * Finish the current buffer @@ -514,8 +522,9 @@ static void em28xx_copy_video(struct em28xx *dev, em28xx_isocdbg("Overflow of %zu bytes past buffer end(2)\n", ((char *)startwrite + lencopy) - ((char *)buf->vb_buf + buf->length)); - lencopy = remain = (char *)buf->vb_buf + buf->length - - (char *)startwrite; + remain = (char *)buf->vb_buf + buf->length - + (char *)startwrite; + lencopy = remain; } if (lencopy <= 0) break; @@ -623,11 +632,11 @@ finish_field_prepare_next(struct em28xx *dev, struct em28xx_v4l2 *v4l2 = dev->v4l2; if (v4l2->progressive || v4l2->top_field) { /* Brand new frame */ - if (buf != NULL) + if (buf) finish_buffer(dev, buf); buf = get_next_buf(dev, dma_q); } - if (buf != NULL) { + if (buf) { buf->top_field = v4l2->top_field; buf->pos = 0; } @@ -648,13 +657,17 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, struct em28xx_dmaqueue *dma_q = &dev->vidq; struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; - /* capture type 0 = vbi start - capture type 1 = vbi in progress - capture type 2 = video start - capture type 3 = video in progress */ + /* + * capture type 0 = vbi start + * capture type 1 = vbi in progress + * capture type 2 = video start + * capture type 3 = video in progress + */ if (data_len >= 4) { - /* NOTE: Headers are always 4 bytes and - * never split across packets */ + /* + * NOTE: Headers are always 4 bytes and + * never split across packets + */ if (data_pkt[0] == 0x88 && data_pkt[1] == 0x88 && data_pkt[2] == 0x88 && data_pkt[3] == 0x88) { /* Continuation */ @@ -677,8 +690,10 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, data_len -= 4; } } - /* NOTE: With bulk transfers, intermediate data packets - * have no continuation header */ + /* + * NOTE: With bulk transfers, intermediate data packets + * have no continuation header + */ if (v4l2->capture_type == 0) { vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q); @@ -692,7 +707,7 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, (vbi_size - v4l2->vbi_read) : data_len; /* Copy VBI data */ - if (vbi_buf != NULL) + if (vbi_buf) em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len); v4l2->vbi_read += vbi_data_len; @@ -710,7 +725,7 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, v4l2->capture_type = 3; } - if (v4l2->capture_type == 3 && buf != NULL && data_len > 0) + if (v4l2->capture_type == 3 && buf && data_len > 0) em28xx_copy_video(dev, buf, data_pkt, data_len); } @@ -727,8 +742,10 @@ static inline void process_frame_data_em25xx(struct em28xx *dev, bool frame_end = false; /* Check for header */ - /* NOTE: at least with bulk transfers, only the first packet - * has a header and has always set the FRAME_END bit */ + /* + * NOTE: at least with bulk transfers, only the first packet + * has a header and has always set the FRAME_END bit + */ if (data_len >= 2) { /* em25xx header is only 2 bytes long */ if ((data_pkt[0] == EM25XX_FRMDATAHDR_BYTE1) && ((data_pkt[1] & ~EM25XX_FRMDATAHDR_BYTE2_MASK) == 0x00)) { @@ -745,14 +762,15 @@ static inline void process_frame_data_em25xx(struct em28xx *dev, buf = finish_field_prepare_next(dev, buf, dmaq); dev->usb_ctl.vid_buf = buf; } - /* NOTE: in ISOC mode when a new frame starts and buf==NULL, + /* + * NOTE: in ISOC mode when a new frame starts and buf==NULL, * we COULD already prepare a buffer here to avoid skipping the * first frame. */ } /* Copy data */ - if (buf != NULL && data_len > 0) + if (buf && data_len > 0) em28xx_copy_video(dev, buf, data_pkt, data_len); /* Finish frame (ISOC only) => avoids lag of 1 frame */ @@ -761,14 +779,17 @@ static inline void process_frame_data_em25xx(struct em28xx *dev, dev->usb_ctl.vid_buf = buf; } - /* NOTE: Tested with USB bulk transfers only ! + /* + * NOTES: + * + * 1) Tested with USB bulk transfers only ! * The wording in the datasheet suggests that isoc might work different. * The current code assumes that with isoc transfers each packet has a * header like with the other em28xx devices. + * + * 2) Support for interlaced mode is pure theory. It has not been + * tested and it is unknown if these devices actually support it. */ - /* NOTE: Support for interlaced mode is pure theory. It has not been - * tested and it is unknown if these devices actually support it. */ - /* NOTE: No VBI support yet (these chips likely do not support VBI). */ } /* Processes and copies the URB data content (video and VBI data) */ @@ -829,12 +850,11 @@ static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) else process_frame_data_em28xx(dev, usb_data_pkt, usb_data_len); - } return 1; } -static int get_ressource(enum v4l2_buf_type f_type) +static int get_resource(enum v4l2_buf_type f_type) { switch (f_type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -842,14 +862,15 @@ static int get_ressource(enum v4l2_buf_type f_type) case V4L2_BUF_TYPE_VBI_CAPTURE: return EM28XX_RESOURCE_VBI; default: - BUG(); + WARN_ON(1); + return -1; /* Indicate that device is busy */ } } /* Usage lock check functions */ static int res_get(struct em28xx *dev, enum v4l2_buf_type f_type) { - int res_type = get_ressource(f_type); + int res_type = get_resource(f_type); /* is it free? */ if (dev->resources & res_type) { @@ -865,7 +886,7 @@ static int res_get(struct em28xx *dev, enum v4l2_buf_type f_type) static void res_free(struct em28xx *dev, enum v4l2_buf_type f_type) { - int res_type = get_ressource(f_type); + int res_type = get_resource(f_type); dev->resources &= ~res_type; em28xx_videodbg("res: put %d\n", res_type); @@ -937,10 +958,11 @@ static int em28xx_enable_analog_tuner(struct em28xx *dev) flags ? "enabled" : "disabled", ret); return ret; - } else - em28xx_videodbg("link %s->%s was %s\n", - source->name, sink->name, - flags ? "ENABLED" : "disabled"); + } + + em28xx_videodbg("link %s->%s was %s\n", + source->name, sink->name, + flags ? "ENABLED" : "disabled"); } #endif return 0; @@ -976,7 +998,7 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) } /* Webcams don't have input connectors */ - if (dev->board.is_webcam) + if (dev->is_webcam) return; /* Create entities for each input connector */ @@ -1016,10 +1038,9 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) #endif } - -/* ------------------------------------------------------------------ - Videobuf2 operations - ------------------------------------------------------------------*/ +/* + * Videobuf2 operations + */ static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes, @@ -1072,8 +1093,10 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) em28xx_videodbg("%s\n", __func__); - /* Make sure streaming is not already in progress for this type - of filehandle (e.g. video, vbi) */ + /* + * Make sure streaming is not already in progress for this type + * of filehandle (e.g. video, vbi) + */ rc = res_get(dev, vq->type); if (rc) return rc; @@ -1084,9 +1107,10 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) /* Allocate the USB bandwidth */ em28xx_set_alternate(dev); - /* Needed, since GPIO might have disabled power of - some i2c device - */ + /* + * Needed, since GPIO might have disabled power of + * some i2c device + */ em28xx_wake_i2c(dev); v4l2->capture_type = -1; @@ -1145,7 +1169,7 @@ static void em28xx_stop_streaming(struct vb2_queue *vq) } spin_lock_irqsave(&dev->slock, flags); - if (dev->usb_ctl.vid_buf != NULL) { + if (dev->usb_ctl.vid_buf) { vb2_buffer_done(&dev->usb_ctl.vid_buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); dev->usb_ctl.vid_buf = NULL; @@ -1180,7 +1204,7 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq) } spin_lock_irqsave(&dev->slock, flags); - if (dev->usb_ctl.vbi_buf != NULL) { + if (dev->usb_ctl.vbi_buf) { vb2_buffer_done(&dev->usb_ctl.vbi_buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); dev->usb_ctl.vbi_buf = NULL; @@ -1261,7 +1285,9 @@ static int em28xx_vb2_setup(struct em28xx *dev) return 0; } -/********************* v4l2 interface **************************************/ +/* + * v4l2 interface + */ static void video_mux(struct em28xx *dev, int index) { @@ -1277,7 +1303,7 @@ static void video_mux(struct em28xx *dev, int index) v4l2_device_call_all(v4l2_dev, 0, video, s_routing, INPUT(index)->vmux, 0, 0); - if (dev->board.has_msp34xx) { + if (dev->has_msp34xx) { if (dev->i2s_speed) { v4l2_device_call_all(v4l2_dev, 0, audio, s_i2s_clock_freq, dev->i2s_speed); @@ -1394,9 +1420,9 @@ static void scale_to_size(struct em28xx *dev, *height = 1; } -/* ------------------------------------------------------------------ - IOCTL vidioc handling - ------------------------------------------------------------------*/ +/* + * IOCTL vidioc handling + */ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) @@ -1462,8 +1488,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, if (width == maxw && height == maxh) width /= 2; } else { - /* width must even because of the YUYV format - height must be even because of interlacing */ + /* + * width must even because of the YUYV format + * height must be even because of interlacing + */ v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); } @@ -1493,7 +1521,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, - unsigned width, unsigned height) + unsigned int width, unsigned int height) { struct em28xx_fmt *fmt; struct em28xx_v4l2 *v4l2 = dev->v4l2; @@ -1582,17 +1610,26 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) static int vidioc_g_parm(struct file *file, void *priv, struct v4l2_streamparm *p) { + struct v4l2_subdev_frame_interval ival = { 0 }; struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev->v4l2; int rc = 0; + if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; + p->parm.capture.readbuffers = EM28XX_MIN_BUF; - if (dev->board.is_webcam) + p->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + if (dev->is_webcam) { rc = v4l2_device_call_until_err(&v4l2->v4l2_dev, 0, - video, g_parm, p); - else + video, g_frame_interval, &ival); + if (!rc) + p->parm.capture.timeperframe = ival.interval; + } else { v4l2_video_std_frame_period(v4l2->norm, &p->parm.capture.timeperframe); + } return rc; } @@ -1601,10 +1638,27 @@ static int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *p) { struct em28xx *dev = video_drvdata(file); + struct v4l2_subdev_frame_interval ival = { + 0, + p->parm.capture.timeperframe + }; + int rc = 0; + + if (!dev->is_webcam) + return -ENOTTY; + + if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; + memset(&p->parm, 0, sizeof(p->parm)); p->parm.capture.readbuffers = EM28XX_MIN_BUF; - return v4l2_device_call_until_err(&dev->v4l2->v4l2_dev, - 0, video, s_parm, p); + p->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + rc = v4l2_device_call_until_err(&dev->v4l2->v4l2_dev, 0, + video, s_frame_interval, &ival); + if (!rc) + p->parm.capture.timeperframe = ival.interval; + return rc; } static int vidioc_enum_input(struct file *file, void *priv, @@ -1616,20 +1670,19 @@ static int vidioc_enum_input(struct file *file, void *priv, n = i->index; if (n >= MAX_EM28XX_INPUT) return -EINVAL; - if (0 == INPUT(n)->type) + if (!INPUT(n)->type) return -EINVAL; - i->index = n; i->type = V4L2_INPUT_TYPE_CAMERA; strcpy(i->name, iname[INPUT(n)->type]); - if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type)) + if (INPUT(n)->type == EM28XX_VMUX_TELEVISION) i->type = V4L2_INPUT_TYPE_TUNER; i->std = dev->v4l2->vdev.tvnorms; /* webcams do not have the STD API */ - if (dev->board.is_webcam) + if (dev->is_webcam) i->capabilities = 0; return 0; @@ -1650,7 +1703,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) if (i >= MAX_EM28XX_INPUT) return -EINVAL; - if (0 == INPUT(i)->type) + if (!INPUT(i)->type) return -EINVAL; video_mux(dev, i); @@ -1696,13 +1749,14 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) return 0; } -static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a) +static int vidioc_s_audio(struct file *file, void *priv, + const struct v4l2_audio *a) { struct em28xx *dev = video_drvdata(file); if (a->index >= MAX_EM28XX_INPUT) return -EINVAL; - if (0 == INPUT(a->index)->type) + if (!INPUT(a->index)->type) return -EINVAL; dev->ctl_ainput = INPUT(a->index)->amux; @@ -1719,7 +1773,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, { struct em28xx *dev = video_drvdata(file); - if (0 != t->index) + if (t->index != 0) return -EINVAL; strcpy(t->name, "Tuner"); @@ -1733,7 +1787,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, { struct em28xx *dev = video_drvdata(file); - if (0 != t->index) + if (t->index != 0) return -EINVAL; v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t); @@ -1746,7 +1800,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev->v4l2; - if (0 != f->tuner) + if (f->tuner != 0) return -EINVAL; f->frequency = v4l2->frequency; @@ -1760,7 +1814,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev->v4l2; - if (0 != f->tuner) + if (f->tuner != 0) return -EINVAL; v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_frequency, f); @@ -1884,8 +1938,9 @@ static int vidioc_querycap(struct file *file, void *priv, if (dev->tuner_type != TUNER_ABSENT) cap->device_caps |= V4L2_CAP_TUNER; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | - V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | + V4L2_CAP_DEVICE_CAPS | V4L2_CAP_READWRITE | + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; if (video_is_registered(&v4l2->vbi_dev)) cap->capabilities |= V4L2_CAP_VBI_CAPTURE; if (video_is_registered(&v4l2->radio_dev)) @@ -1978,9 +2033,9 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, return 0; } -/* ----------------------------------------------------------- */ -/* RADIO ESPECIFIC IOCTLS */ -/* ----------------------------------------------------------- */ +/* + * RADIO ESPECIFIC IOCTLS + */ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) @@ -2002,7 +2057,7 @@ static int radio_s_tuner(struct file *file, void *priv, { struct em28xx *dev = video_drvdata(file); - if (0 != t->index) + if (t->index != 0) return -EINVAL; v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t); @@ -2097,7 +2152,7 @@ static int em28xx_v4l2_open(struct file *filp) * em28xx_v4l2_fini() * unregisters the v4l2,i2c and usb devices * called when the device gets disconected or at module unload -*/ + */ static int em28xx_v4l2_fini(struct em28xx *dev) { struct em28xx_v4l2 *v4l2 = dev->v4l2; @@ -2112,7 +2167,7 @@ static int em28xx_v4l2_fini(struct em28xx *dev) return 0; } - if (v4l2 == NULL) + if (!v4l2) return 0; dev_info(&dev->intf->dev, "Closing video extension\n"); @@ -2127,17 +2182,17 @@ static int em28xx_v4l2_fini(struct em28xx *dev) if (video_is_registered(&v4l2->radio_dev)) { dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->radio_dev)); + video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->vbi_dev)); + video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->vdev)); + video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); } @@ -2189,7 +2244,7 @@ static int em28xx_v4l2_close(struct file *filp) struct em28xx *dev = video_drvdata(filp); struct em28xx_v4l2 *v4l2 = dev->v4l2; struct usb_device *udev = interface_to_usbdev(dev->intf); - int errCode; + int err; em28xx_videodbg("users=%d\n", v4l2->users); @@ -2202,7 +2257,7 @@ static int em28xx_v4l2_close(struct file *filp) goto exit; /* Save some power by putting tuner to sleep */ - v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); + v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, standby); /* do this before setting alternate! */ em28xx_set_mode(dev, EM28XX_SUSPEND); @@ -2210,11 +2265,11 @@ static int em28xx_v4l2_close(struct file *filp) /* set alternate 0 */ dev->alt = 0; em28xx_videodbg("setting alternate 0\n"); - errCode = usb_set_interface(udev, 0, 0); - if (errCode < 0) { + err = usb_set_interface(udev, 0, 0); + if (err < 0) { dev_err(&dev->intf->dev, "cannot change alternate number to 0 (error=%i)\n", - errCode); + err); } } @@ -2343,7 +2398,7 @@ static void em28xx_vdev_init(struct em28xx *dev, *vfd = *template; vfd->v4l2_dev = &dev->v4l2->v4l2_dev; vfd->lock = &dev->lock; - if (dev->board.is_webcam) + if (dev->is_webcam) vfd->tvnorms = 0; snprintf(vfd->name, sizeof(vfd->name), "%s %s", @@ -2372,7 +2427,7 @@ static void em28xx_tuner_setup(struct em28xx *dev, unsigned short tuner_addr) 0, tuner, s_type_addr, &tun_setup); } - if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) { + if (dev->tuner_type != TUNER_ABSENT && dev->tuner_type) { tun_setup.type = dev->tuner_type; tun_setup.addr = tuner_addr; @@ -2435,7 +2490,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) mutex_lock(&dev->lock); - v4l2 = kzalloc(sizeof(struct em28xx_v4l2), GFP_KERNEL); + v4l2 = kzalloc(sizeof(*v4l2), GFP_KERNEL); if (!v4l2) { mutex_unlock(&dev->lock); return -ENOMEM; @@ -2458,7 +2513,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) v4l2_ctrl_handler_init(hdl, 8); v4l2->v4l2_dev.ctrl_handler = hdl; - if (dev->board.is_webcam) + if (dev->is_webcam) v4l2->progressive = true; /* @@ -2470,7 +2525,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* request some modules */ - if (dev->board.has_msp34xx) + if (dev->has_msp34xx) v4l2_i2c_new_subdev(&v4l2->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], "msp3400", 0, msp3400_addrs); @@ -2559,7 +2614,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) INIT_LIST_HEAD(&dev->vidq.active); INIT_LIST_HEAD(&dev->vbiq.active); - if (dev->board.has_msp34xx) { + if (dev->has_msp34xx) { /* Send a reset to other chips via gpio */ ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); if (ret < 0) { @@ -2568,7 +2623,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) __func__, ret); goto unregister_dev; } - msleep(3); + usleep_range(10000, 11000); ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); if (ret < 0) { @@ -2577,7 +2632,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) __func__, ret); goto unregister_dev; } - msleep(3); + usleep_range(10000, 11000); } /* set default norm */ @@ -2589,8 +2644,10 @@ static int em28xx_v4l2_init(struct em28xx *dev) v4l2->format = &format[0]; maxw = norm_maxw(dev); - /* MaxPacketSize for em2800 is too small to capture at full resolution - * use half of maxw as the scaler can only scale to 50% */ + /* + * MaxPacketSize for em2800 is too small to capture at full resolution + * use half of maxw as the scaler can only scale to 50% + */ if (dev->board.is_em2800) maxw /= 2; @@ -2611,29 +2668,33 @@ static int em28xx_v4l2_init(struct em28xx *dev) em28xx_set_outfmt(dev); /* Add image controls */ - /* NOTE: at this point, the subdevices are already registered, so bridge - * controls are only added/enabled when no subdevice provides them */ - if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_CONTRAST)) + + /* + * NOTE: at this point, the subdevices are already registered, so + * bridge controls are only added/enabled when no subdevice provides + * them + */ + if (!v4l2_ctrl_find(hdl, V4L2_CID_CONTRAST)) v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, V4L2_CID_CONTRAST, 0, 0x1f, 1, CONTRAST_DEFAULT); - if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BRIGHTNESS)) + if (!v4l2_ctrl_find(hdl, V4L2_CID_BRIGHTNESS)) v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, V4L2_CID_BRIGHTNESS, -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT); - if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SATURATION)) + if (!v4l2_ctrl_find(hdl, V4L2_CID_SATURATION)) v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, V4L2_CID_SATURATION, 0, 0x1f, 1, SATURATION_DEFAULT); - if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BLUE_BALANCE)) + if (!v4l2_ctrl_find(hdl, V4L2_CID_BLUE_BALANCE)) v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT); - if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_RED_BALANCE)) + if (!v4l2_ctrl_find(hdl, V4L2_CID_RED_BALANCE)) v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, RED_BALANCE_DEFAULT); - if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SHARPNESS)) + if (!v4l2_ctrl_find(hdl, V4L2_CID_SHARPNESS)) v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, V4L2_CID_SHARPNESS, 0, 0x0f, 1, SHARPNESS_DEFAULT); @@ -2653,7 +2714,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) v4l2->vdev.queue->lock = &v4l2->vb_queue_lock; /* disable inapplicable ioctls */ - if (dev->board.is_webcam) { + if (dev->is_webcam) { v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_QUERYSTD); v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_G_STD); v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_S_STD); @@ -2683,7 +2744,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* Allocate and fill vbi video_device struct */ if (em28xx_vbi_supported(dev) == 1) { em28xx_vdev_init(dev, &v4l2->vbi_dev, &em28xx_video_template, - "vbi"); + "vbi"); v4l2->vbi_dev.queue = &v4l2->vb_vbiq; v4l2->vbi_dev.queue->lock = &v4l2->vb_vbi_queue_lock; @@ -2713,7 +2774,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { em28xx_vdev_init(dev, &v4l2->radio_dev, &em28xx_radio_template, - "radio"); + "radio"); ret = video_register_device(&v4l2->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { @@ -2749,7 +2810,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) video_device_node_name(&v4l2->vbi_dev)); /* Save some power by putting tuner to sleep */ - v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); + v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, standby); /* initialize videobuf2 stuff */ em28xx_vb2_setup(dev); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 88084f24f033..63c7c6124707 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -1,31 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* - em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices - - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> - Mauro Carvalho Chehab <mchehab@infradead.org> - Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> - - 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices + * + * Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> + * Ludovico Cavedon <cavedon@sssup.it> + * Mauro Carvalho Chehab <mchehab@infradead.org> + * Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> + * + * Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> + * + * 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. */ #ifndef _EM28XX_H #define _EM28XX_H +#include <linux/bitfield.h> + #define EM28XX_VERSION "0.2.2" #define DRIVER_DESC "Empia em28xx device driver" @@ -166,7 +165,7 @@ #define EM28XX_STOP_AUDIO 0 /* maximum number of em28xx boards */ -#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ +#define EM28XX_MAXBOARDS DVB_MAX_ADAPTERS /* All adapters could be em28xx */ /* maximum number of frames that can be queued */ #define EM28XX_NUM_FRAMES 5 @@ -180,43 +179,32 @@ /* max number of I2C buses on em28xx devices */ #define NUM_I2C_BUSES 2 -/* isoc transfers: number of packets for each buffer - windows requests only 64 packets .. so we better do the same - this is what I found out for all alternate numbers there! +/* + * isoc transfers: number of packets for each buffer + * windows requests only 64 packets .. so we better do the same + * this is what I found out for all alternate numbers there! */ #define EM28XX_NUM_ISOC_PACKETS 64 #define EM28XX_DVB_NUM_ISOC_PACKETS 64 -/* bulk transfers: transfer buffer size = packet size * packet multiplier - USB 2.0 spec says bulk packet size is always 512 bytes +/* + * bulk transfers: transfer buffer size = packet size * packet multiplier + * USB 2.0 spec says bulk packet size is always 512 bytes */ #define EM28XX_BULK_PACKET_MULTIPLIER 384 -#define EM28XX_DVB_BULK_PACKET_MULTIPLIER 384 +#define EM28XX_DVB_BULK_PACKET_MULTIPLIER 94 #define EM28XX_INTERLACED_DEFAULT 1 -/* - * Time in msecs to wait for i2c xfers to finish. - * 35ms is the maximum time a SMBUS device could wait when - * clock stretching is used. As the transfer itself will take - * some time to happen, set it to 35 ms. - * - * Ok, I2C doesn't specify any limit. So, eventually, we may need - * to increase this timeout. - * - * FIXME: this assumes that an I2C message is not longer than 1ms. - * This is actually dependent on the I2C bus speed, although most - * devices use a 100kHz clock. So, this assumtion is true most of - * the time. - */ -#define EM28XX_I2C_XFER_TIMEOUT 36 - /* time in msecs to wait for AC97 xfers to finish */ #define EM28XX_AC97_XFER_TIMEOUT 100 /* max. number of button state polling addresses */ #define EM28XX_NUM_BUTTON_ADDRESSES_MAX 5 +#define PRIMARY_TS 0 +#define SECONDARY_TS 1 + enum em28xx_mode { EM28XX_SUSPEND, EM28XX_ANALOG_MODE, @@ -225,64 +213,83 @@ enum em28xx_mode { struct em28xx; +/** + * struct em28xx_usb_bufs - Contains URB-related buffer data + * + * @max_pkt_size: max packet size of isoc transaction + * @num_packets: number of packets in each buffer + * @num_bufs: number of allocated urb + * @urb: urb for isoc/bulk transfers + * @buf: transfer buffers for isoc/bulk transfer + */ struct em28xx_usb_bufs { - /* max packet size of isoc transaction */ int max_pkt_size; - - /* number of packets in each buffer */ int num_packets; - - /* number of allocated urbs */ int num_bufs; - - /* urb for isoc/bulk transfers */ struct urb **urb; - - /* transfer buffers for isoc/bulk transfer */ - char **transfer_buffer; + char **buf; }; +/** + * struct em28xx_usb_ctl - Contains URB-related buffer data + * + * @analog_bufs: isoc/bulk transfer buffers for analog mode + * @digital_bufs: isoc/bulk transfer buffers for digital mode + * @vid_buf: Stores already requested video buffers + * @vbi_buf: Stores already requested VBI buffers + * @urb_data_copy: copy data from URB + */ struct em28xx_usb_ctl { - /* isoc/bulk transfer buffers for analog mode */ struct em28xx_usb_bufs analog_bufs; - - /* isoc/bulk transfer buffers for digital mode */ struct em28xx_usb_bufs digital_bufs; - - /* Stores already requested buffers */ struct em28xx_buffer *vid_buf; struct em28xx_buffer *vbi_buf; - - /* copy data from URB */ int (*urb_data_copy)(struct em28xx *dev, struct urb *urb); - }; -/* Struct to enumberate video formats */ +/** + * struct em28xx_fmt - Struct to enumberate video formats + * + * @name: Name for the video standard + * @fourcc: v4l2 format id + * @depth: mean number of bits to represent a pixel + * @reg: em28xx register value to set it + */ struct em28xx_fmt { - char *name; - u32 fourcc; /* v4l2 format id */ - int depth; - int reg; + char *name; + u32 fourcc; + int depth; + int reg; }; -/* buffer for one video frame */ +/** + * struct em28xx_buffer- buffer for storing one video frame + * + * @vb: common v4l buffer stuff + * @list: List to associate it with the other buffers + * @mem: pointer to the buffer, as returned by vb2_plane_vaddr() + * @length: length of the buffer, as returned by vb2_plane_size() + * @top_field: If non-zero, indicate that the buffer is the top field + * @pos: Indicate the next position of the buffer to be filled. + * @vb_buf: pointer to vmalloc memory address in vb + * + * .. note:: + * + * in interlaced mode, @pos is reset to zero at the start of each new + * field (not frame !) + */ struct em28xx_buffer { - /* common v4l buffer stuff -- must be first */ - struct vb2_v4l2_buffer vb; - struct list_head list; + struct vb2_v4l2_buffer vb; /* must be first */ - void *mem; - unsigned int length; - int top_field; + struct list_head list; - /* counter to control buffer fill */ - unsigned int pos; - /* NOTE; in interlaced mode, this value is reset to zero at - * the start of each new field (not frame !) */ + void *mem; + unsigned int length; + int top_field; - /* pointer to vmalloc memory address in vb */ - char *vb_buf; + unsigned int pos; + + char *vb_buf; }; struct em28xx_dmaqueue { @@ -324,20 +331,48 @@ enum em28xx_usb_audio_type { EM28XX_USB_AUDIO_VENDOR, }; -/* em28xx has two audio inputs: tuner and line in. - However, on most devices, an auxiliary AC97 codec device is used. - The AC97 device may have several different inputs and outputs, - depending on their model. So, it is possible to use AC97 mixer to - address more than two different entries. +/** + * em28xx_amux - describes the type of audio input used by em28xx + * + * @EM28XX_AMUX_VIDEO: + * On devices without AC97, this is the only value that it is currently + * allowed. + * On devices with AC97, it corresponds to the AC97 mixer "Video" control. + * @EM28XX_AMUX_LINE_IN: + * Only for devices with AC97. Corresponds to AC97 mixer "Line In". + * @EM28XX_AMUX_VIDEO2: + * Only for devices with AC97. It means that em28xx should use "Line In" + * And AC97 should use the "Video" mixer control. + * @EM28XX_AMUX_PHONE: + * Only for devices with AC97. Corresponds to AC97 mixer "Phone". + * @EM28XX_AMUX_MIC: + * Only for devices with AC97. Corresponds to AC97 mixer "Mic". + * @EM28XX_AMUX_CD: + * Only for devices with AC97. Corresponds to AC97 mixer "CD". + * @EM28XX_AMUX_AUX: + * Only for devices with AC97. Corresponds to AC97 mixer "Aux". + * @EM28XX_AMUX_PCM_OUT: + * Only for devices with AC97. Corresponds to AC97 mixer "PCM out". + * + * The em28xx chip itself has only two audio inputs: tuner and line in. + * On almost all devices, only the tuner input is used. + * + * However, on most devices, an auxiliary AC97 codec device is used, + * usually connected to the em28xx tuner input (except for + * @EM28XX_AMUX_LINE_IN). + * + * The AC97 device typically have several different inputs and outputs. + * The exact number and description depends on their model. + * + * It is possible to AC97 to mixer more than one different entries at the + * same time, via the alsa mux. */ enum em28xx_amux { - /* This is the only entry for em28xx tuner input */ - EM28XX_AMUX_VIDEO, /* em28xx tuner, AC97 mixer Video */ - - EM28XX_AMUX_LINE_IN, /* AC97 mixer Line In */ + EM28XX_AMUX_VIDEO, + EM28XX_AMUX_LINE_IN, /* Some less-common mixer setups */ - EM28XX_AMUX_VIDEO2, /* em28xx Line in, AC97 mixer Video */ + EM28XX_AMUX_VIDEO2, EM28XX_AMUX_PHONE, EM28XX_AMUX_MIC, EM28XX_AMUX_CD, @@ -347,14 +382,14 @@ enum em28xx_amux { enum em28xx_aout { /* AC97 outputs */ - EM28XX_AOUT_MASTER = 1 << 0, - EM28XX_AOUT_LINE = 1 << 1, - EM28XX_AOUT_MONO = 1 << 2, - EM28XX_AOUT_LFE = 1 << 3, - EM28XX_AOUT_SURR = 1 << 4, + EM28XX_AOUT_MASTER = BIT(0), + EM28XX_AOUT_LINE = BIT(1), + EM28XX_AOUT_MONO = BIT(2), + EM28XX_AOUT_LFE = BIT(3), + EM28XX_AOUT_SURR = BIT(4), /* PCM IN Mixer - used by AC97_RECORD_SELECT register */ - EM28XX_AOUT_PCM_IN = 1 << 7, + EM28XX_AOUT_PCM_IN = BIT(7), /* Bits 10-8 are used to indicate the PCM IN record select */ EM28XX_AOUT_PCM_MIC_PCM = 0 << 8, @@ -383,7 +418,7 @@ struct em28xx_input { unsigned int vmux; enum em28xx_amux amux; enum em28xx_aout aout; - struct em28xx_reg_seq *gpio; + const struct em28xx_reg_seq *gpio; }; #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) @@ -441,22 +476,23 @@ struct em28xx_board { int vchannels; int tuner_type; int tuner_addr; - unsigned def_i2c_bus; /* Default I2C bus */ + unsigned int def_i2c_bus; /* Default I2C bus */ /* i2c flags */ unsigned int tda9887_conf; /* GPIO sequences */ - struct em28xx_reg_seq *dvb_gpio; - struct em28xx_reg_seq *suspend_gpio; - struct em28xx_reg_seq *tuner_gpio; - struct em28xx_reg_seq *mute_gpio; + const struct em28xx_reg_seq *dvb_gpio; + const struct em28xx_reg_seq *suspend_gpio; + const struct em28xx_reg_seq *tuner_gpio; + const struct em28xx_reg_seq *mute_gpio; unsigned int is_em2800:1; unsigned int has_msp34xx:1; unsigned int mts_firmware:1; unsigned int max_range_640_480:1; unsigned int has_dvb:1; + unsigned int has_dual_ts:1; unsigned int is_webcam:1; unsigned int valid:1; unsigned int has_ir_i2c:1; @@ -476,7 +512,7 @@ struct em28xx_board { struct em28xx_led *leds; /* Buttons */ - struct em28xx_button *buttons; + const struct em28xx_button *buttons; }; struct em28xx_eeprom { @@ -519,8 +555,8 @@ struct em28xx_v4l2 { /* Videobuf2 */ struct vb2_queue vb_vidq; struct vb2_queue vb_vbiq; - struct mutex vb_queue_lock; - struct mutex vb_vbi_queue_lock; + struct mutex vb_queue_lock; /* Protects vb_vidq */ + struct mutex vb_vbi_queue_lock; /* Protects vb_vbiq */ u8 vinmode; u8 vinctl; @@ -546,8 +582,8 @@ struct em28xx_v4l2 { /* Frame properties */ int width; /* current frame width */ int height; /* current frame height */ - unsigned hscale; /* horizontal scale factor (see datasheet) */ - unsigned vscale; /* vertical scale factor (see datasheet) */ + unsigned int hscale; /* horizontal scale factor (see datasheet) */ + unsigned int vscale; /* vertical scale factor (see datasheet) */ unsigned int vbi_width; unsigned int vbi_height; /* lines per field */ @@ -565,7 +601,7 @@ struct em28xx_v4l2 { struct em28xx_audio { char name[50]; - unsigned num_urb; + unsigned int num_urb; char **transfer_buffer; struct urb **urb; struct usb_device *udev; @@ -578,7 +614,7 @@ struct em28xx_audio { size_t period; int users; - spinlock_t slock; + spinlock_t slock; /* Protects struct em28xx_audio */ /* Controls streaming */ struct work_struct wq_trigger; /* trigger to start/stop audio */ @@ -596,7 +632,7 @@ enum em28xx_i2c_algo_type { struct em28xx_i2c_bus { struct em28xx *dev; - unsigned bus; + unsigned int bus; enum em28xx_i2c_algo_type algo_type; }; @@ -604,102 +640,111 @@ struct em28xx_i2c_bus { struct em28xx { struct kref ref; - /* Sub-module data */ + // Sub-module data struct em28xx_v4l2 *v4l2; struct em28xx_dvb *dvb; struct em28xx_audio adev; struct em28xx_IR *ir; - /* generic device properties */ - int model; /* index in the device_data struct */ - int devno; /* marks the number of this device */ + // generic device properties + int model; // index in the device_data struct + int devno; // marks the number of this device enum em28xx_chip_id chip_id; - unsigned int is_em25xx:1; /* em25xx/em276x/7x/8x family bridge */ - unsigned char disconnected:1; /* device has been diconnected */ + unsigned int is_em25xx:1; // em25xx/em276x/7x/8x family bridge + unsigned int disconnected:1; // device has been diconnected unsigned int has_video:1; unsigned int is_audio_only:1; + unsigned int is_webcam:1; + unsigned int has_msp34xx:1; + unsigned int i2c_speed:2; enum em28xx_int_audio_type int_audio_type; enum em28xx_usb_audio_type usb_audio_type; + unsigned char name[32]; struct em28xx_board board; - enum em28xx_sensor em28xx_sensor; /* camera specific */ + enum em28xx_sensor em28xx_sensor; // camera specific - /* Some older em28xx chips needs a waiting time after writing */ + // Some older em28xx chips needs a waiting time after writing unsigned int wait_after_write; struct list_head devlist; - u32 i2s_speed; /* I2S speed for audio digital stream */ + u32 i2s_speed; // I2S speed for audio digital stream struct em28xx_audio_mode audio_mode; - int tuner_type; /* type of the tuner */ + int tuner_type; // type of the tuner - /* i2c i/o */ + // i2c i/o struct i2c_adapter i2c_adap[NUM_I2C_BUSES]; struct i2c_client i2c_client[NUM_I2C_BUSES]; struct em28xx_i2c_bus i2c_bus[NUM_I2C_BUSES]; unsigned char eeprom_addrwidth_16bit:1; - unsigned def_i2c_bus; /* Default I2C bus */ - unsigned cur_i2c_bus; /* Current I2C bus */ + unsigned int def_i2c_bus; // Default I2C bus + unsigned int cur_i2c_bus; // Current I2C bus struct rt_mutex i2c_bus_lock; - /* video for linux */ - unsigned int ctl_input; /* selected input */ - unsigned int ctl_ainput;/* selected audio input */ - unsigned int ctl_aoutput;/* selected audio output */ + // video for linux + unsigned int ctl_input; // selected input + unsigned int ctl_ainput;// selected audio input + unsigned int ctl_aoutput;// selected audio output int mute; int volume; - unsigned long hash; /* eeprom hash - for boards with generic ID */ - unsigned long i2c_hash; /* i2c devicelist hash - - for boards with generic ID */ + unsigned long hash; // eeprom hash - for boards with generic ID + unsigned long i2c_hash; // i2c devicelist hash - + // for boards with generic ID struct work_struct request_module_wk; - /* locks */ - struct mutex lock; + // locks + struct mutex lock; /* protects em28xx struct */ struct mutex ctrl_urb_lock; /* protects urb_buf */ - /* resources in use */ + // resources in use unsigned int resources; - /* eeprom content */ + // eeprom content u8 *eedata; u16 eedata_len; - /* Isoc control struct */ + // Isoc control struct struct em28xx_dmaqueue vidq; struct em28xx_dmaqueue vbiq; struct em28xx_usb_ctl usb_ctl; - spinlock_t slock; - - /* usb transfer */ - struct usb_interface *intf; /* the usb interface */ - u8 ifnum; /* number of the assigned usb interface */ - u8 analog_ep_isoc; /* address of isoc endpoint for analog */ - u8 analog_ep_bulk; /* address of bulk endpoint for analog */ - u8 dvb_ep_isoc; /* address of isoc endpoint for DVB */ - u8 dvb_ep_bulk; /* address of bulk endpoint for DVB */ - int alt; /* alternate setting */ - int max_pkt_size; /* max packet size of the selected ep at alt */ - int packet_multiplier; /* multiplier for wMaxPacketSize, used for - URB buffer size definition */ - int num_alt; /* number of alternative settings */ - unsigned int *alt_max_pkt_size_isoc; /* array of isoc wMaxPacketSize */ - unsigned int analog_xfer_bulk:1; /* use bulk instead of isoc - transfers for analog */ - int dvb_alt_isoc; /* alternate setting for DVB isoc transfers */ - unsigned int dvb_max_pkt_size_isoc; /* isoc max packet size of the - selected DVB ep at dvb_alt */ - unsigned int dvb_xfer_bulk:1; /* use bulk instead of isoc - transfers for DVB */ - char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ - - /* helper funcs that call usb_control_msg */ + + spinlock_t slock; /* Protects em28xx video/vbi/dvb IRQ stream data */ + + // usb transfer + struct usb_interface *intf; // the usb interface + u8 ifnum; // number of the assigned usb interface + u8 analog_ep_isoc; // address of isoc endpoint for analog + u8 analog_ep_bulk; // address of bulk endpoint for analog + u8 dvb_ep_isoc_ts2; // address of isoc endpoint for DVB TS2 + u8 dvb_ep_bulk_ts2; // address of bulk endpoint for DVB TS2 + u8 dvb_ep_isoc; // address of isoc endpoint for DVB + u8 dvb_ep_bulk; // address of bulk endpoint for DVB + int alt; // alternate setting + int max_pkt_size; // max packet size of the selected ep at alt + int packet_multiplier; // multiplier for wMaxPacketSize, used for + // URB buffer size definition + int num_alt; // number of alternative settings + unsigned int *alt_max_pkt_size_isoc; // array of isoc wMaxPacketSize + unsigned int analog_xfer_bulk:1; // use bulk instead of isoc + // transfers for analog + int dvb_alt_isoc; // alternate setting for DVB isoc transfers + unsigned int dvb_max_pkt_size_isoc; // isoc max packet size of the + // selected DVB ep at dvb_alt + unsigned int dvb_max_pkt_size_isoc_ts2; // isoc max packet size of the + // selected DVB ep at dvb_alt + unsigned int dvb_xfer_bulk:1; // use bulk instead of isoc + // transfers for DVB + char urb_buf[URB_MAX_CTRL_SIZE]; // urb control msg buffer + + // helper funcs that call usb_control_msg int (*em28xx_write_regs)(struct em28xx *dev, u16 reg, char *buf, int len); int (*em28xx_read_reg)(struct em28xx *dev, u16 reg); @@ -711,14 +756,14 @@ struct em28xx { enum em28xx_mode mode; - /* Button state polling */ + // Button state polling struct delayed_work buttons_query_work; u8 button_polling_addresses[EM28XX_NUM_BUTTON_ADDRESSES_MAX]; u8 button_polling_last_values[EM28XX_NUM_BUTTON_ADDRESSES_MAX]; u8 num_button_polling_addresses; - u16 button_polling_interval; /* [ms] */ - /* Snapshot button input device */ - char snapshot_button_path[30]; /* path of the input dev */ + u16 button_polling_interval; // [ms] + // Snapshot button input device + char snapshot_button_path[30]; // path of the input dev struct input_dev *sbutton_input_dev; #ifdef CONFIG_MEDIA_CONTROLLER @@ -726,6 +771,9 @@ struct em28xx { struct media_entity input_ent[MAX_EM28XX_INPUT]; struct media_pad input_pad[MAX_EM28XX_INPUT]; #endif + + struct em28xx *dev_next; + int ts; }; #define kref_to_dev(d) container_of(d, struct em28xx, ref) @@ -734,17 +782,17 @@ struct em28xx_ops { struct list_head next; char *name; int id; - int (*init)(struct em28xx *); - int (*fini)(struct em28xx *); - int (*suspend)(struct em28xx *); - int (*resume)(struct em28xx *); + int (*init)(struct em28xx *dev); + int (*fini)(struct em28xx *dev); + int (*suspend)(struct em28xx *dev); + int (*resume)(struct em28xx *dev); }; /* Provided by em28xx-i2c.c */ -void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus); -int em28xx_i2c_register(struct em28xx *dev, unsigned bus, +void em28xx_do_i2c_scan(struct em28xx *dev, unsigned int bus); +int em28xx_i2c_register(struct em28xx *dev, unsigned int bus, enum em28xx_i2c_algo_type algo_type); -int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus); +int em28xx_i2c_unregister(struct em28xx *dev, unsigned int bus); /* Provided by em28xx-core.c */ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, @@ -778,7 +826,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode); void em28xx_stop_urbs(struct em28xx *dev); int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); -int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); +int em28xx_gpio_set(struct em28xx *dev, const struct em28xx_reg_seq *gpio); int em28xx_register_extension(struct em28xx_ops *dev); void em28xx_unregister_extension(struct em28xx_ops *dev); void em28xx_init_extension(struct em28xx *dev); @@ -787,7 +835,7 @@ int em28xx_suspend_extension(struct em28xx *dev); int em28xx_resume_extension(struct em28xx *dev); /* Provided by em28xx-cards.c */ -extern struct em28xx_board em28xx_boards[]; +extern const struct em28xx_board em28xx_boards[]; extern struct usb_device_id em28xx_id_table[]; int em28xx_tuner_callback(void *ptr, int component, int command, int arg); void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl); diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c index c618764480c6..f84a2130f033 100644 --- a/drivers/media/usb/go7007/snd-go7007.c +++ b/drivers/media/usb/go7007/snd-go7007.c @@ -227,7 +227,7 @@ int go7007_snd_init(struct go7007 *go) { static int dev; struct go7007_snd *gosnd; - int ret = 0; + int ret; if (dev >= SNDRV_CARDS) return -ENODEV; diff --git a/drivers/media/usb/gspca/dtcs033.c b/drivers/media/usb/gspca/dtcs033.c index cdf27cf0112a..7654c8c08eda 100644 --- a/drivers/media/usb/gspca/dtcs033.c +++ b/drivers/media/usb/gspca/dtcs033.c @@ -76,12 +76,10 @@ static int reg_reqs(struct gspca_dev *gspca_dev, } else if (preq->bRequestType & USB_DIR_IN) { gspca_dbg(gspca_dev, D_STREAM, - "USB IN (%d) returned[%d] %02X %02X %02X %s\n", + "USB IN (%d) returned[%d] %3ph %s", i, preq->wLength, - gspca_dev->usb_buf[0], - gspca_dev->usb_buf[1], - gspca_dev->usb_buf[2], + gspca_dev->usb_buf, preq->wLength > 3 ? "...\n" : "\n"); } diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 8c2a86d71e8a..82927eb334c4 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -648,8 +648,8 @@ static void s2255_fillbuff(struct s2255_vc *vc, pr_err("s2255: =======no frame\n"); return; } - dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n", - (unsigned long)vbuf, pos); + dprintk(dev, 2, "s2255fill at : Buffer %p size= %d\n", + vbuf, pos); } @@ -803,10 +803,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC) f->fmt.pix.width = LINE_SZ_4CIFS_NTSC; - else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC) - f->fmt.pix.width = LINE_SZ_2CIFS_NTSC; - else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC) - f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; else f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; } else { @@ -820,10 +816,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) f->fmt.pix.width = LINE_SZ_4CIFS_PAL; - else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) - f->fmt.pix.width = LINE_SZ_2CIFS_PAL; - else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) - f->fmt.pix.width = LINE_SZ_1CIFS_PAL; else f->fmt.pix.width = LINE_SZ_1CIFS_PAL; } diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index f13e4b01b5a5..6d436e9e454f 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -179,8 +179,7 @@ static int smsusb_submit_urb(struct smsusb_device_t *dev, smsusb_onresponse, surb ); - surb->urb.transfer_dma = surb->cb->phys; - surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + surb->urb.transfer_flags |= URB_FREE_BUFFER; return usb_submit_urb(&surb->urb, GFP_ATOMIC); } @@ -446,6 +445,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) dev->in_ep, dev->out_ep); params.device = &dev->udev->dev; + params.usb_device = dev->udev; params.buffer_size = dev->buffer_size; params.num_buffers = MAX_BUFFERS; params.sendrequest_handler = smsusb_sendrequest; diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c index 4d5f4cc4887e..70939e96b856 100644 --- a/drivers/media/usb/tm6000/tm6000-cards.c +++ b/drivers/media/usb/tm6000/tm6000-cards.c @@ -1174,7 +1174,7 @@ static int tm6000_usb_probe(struct usb_interface *interface, { struct usb_device *usbdev; struct tm6000_core *dev; - int i, rc = 0; + int i, rc; int nr = 0; char *speed; diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 8314d3fa9241..b2399d4266da 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -1346,9 +1346,8 @@ static int __tm6000_open(struct file *file) fh->width = dev->width; fh->height = dev->height; - dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n", - (unsigned long)fh, (unsigned long)dev, - (unsigned long)&dev->vidq); + dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=%p, dev=%p, dev->vidq=%p\n", + fh, dev, &dev->vidq); dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty queued=%d\n", list_empty(&dev->vidq.queued)); dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty active=%d\n", diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c index 127f8a0c098b..5095c380b2c1 100644 --- a/drivers/media/usb/usbtv/usbtv-core.c +++ b/drivers/media/usb/usbtv/usbtv-core.c @@ -112,6 +112,8 @@ static int usbtv_probe(struct usb_interface *intf, return 0; usbtv_audio_fail: + /* we must not free at this point */ + usb_get_dev(usbtv->udev); usbtv_video_free(usbtv); usbtv_video_fail: @@ -145,6 +147,7 @@ static void usbtv_disconnect(struct usb_interface *intf) static const struct usb_device_id usbtv_id_table[] = { { USB_DEVICE(0x1b71, 0x3002) }, { USB_DEVICE(0x1f71, 0x3301) }, + { USB_DEVICE(0x1f71, 0x3306) }, {} }; MODULE_DEVICE_TABLE(usb, usbtv_id_table); diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 20397aba6849..102594ec3e97 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -366,10 +366,10 @@ static struct uvc_menu_info exposure_auto_controls[] = { { 8, "Aperture Priority Mode" }, }; -static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, - __u8 query, const __u8 *data) +static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, + u8 query, const u8 *data) { - __s8 zoom = (__s8)data[0]; + s8 zoom = (s8)data[0]; switch (query) { case UVC_GET_CUR: @@ -385,17 +385,17 @@ static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, } static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping, - __s32 value, __u8 *data) + s32 value, u8 *data) { data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff; data[2] = min((int)abs(value), 0xff); } -static __s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, - __u8 query, const __u8 *data) +static s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, + u8 query, const u8 *data) { unsigned int first = mapping->offset / 8; - __s8 rel = (__s8)data[first]; + s8 rel = (s8)data[first]; switch (query) { case UVC_GET_CUR: @@ -412,7 +412,7 @@ static __s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, } static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping, - __s32 value, __u8 *data) + s32 value, u8 *data) { unsigned int first = mapping->offset / 8; @@ -745,17 +745,17 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { * Utility functions */ -static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) +static inline u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) { return ctrl->uvc_data + id * ctrl->info.size; } -static inline int uvc_test_bit(const __u8 *data, int bit) +static inline int uvc_test_bit(const u8 *data, int bit) { return (data[bit >> 3] >> (bit & 7)) & 1; } -static inline void uvc_clear_bit(__u8 *data, int bit) +static inline void uvc_clear_bit(u8 *data, int bit) { data[bit >> 3] &= ~(1 << (bit & 7)); } @@ -765,20 +765,20 @@ static inline void uvc_clear_bit(__u8 *data, int bit) * a signed 32bit integer. Sign extension will be performed if the mapping * references a signed data type. */ -static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping, - __u8 query, const __u8 *data) +static s32 uvc_get_le_value(struct uvc_control_mapping *mapping, + u8 query, const u8 *data) { int bits = mapping->size; int offset = mapping->offset; - __s32 value = 0; - __u8 mask; + s32 value = 0; + u8 mask; data += offset / 8; offset &= 7; mask = ((1LL << bits) - 1) << offset; for (; bits > 0; data++) { - __u8 byte = *data & mask; + u8 byte = *data & mask; value |= offset > 0 ? (byte >> offset) : (byte << (-offset)); bits -= 8 - (offset > 0 ? offset : 0); offset -= 8; @@ -796,11 +796,11 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping, * in the little-endian data stored at 'data' to the value 'value'. */ static void uvc_set_le_value(struct uvc_control_mapping *mapping, - __s32 value, __u8 *data) + s32 value, u8 *data) { int bits = mapping->size; int offset = mapping->offset; - __u8 mask; + u8 mask; /* According to the v4l2 spec, writing any value to a button control * should result in the action belonging to the button control being @@ -826,13 +826,13 @@ static void uvc_set_le_value(struct uvc_control_mapping *mapping, * Terminal and unit management */ -static const __u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; -static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA; -static const __u8 uvc_media_transport_input_guid[16] = +static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; +static const u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA; +static const u8 uvc_media_transport_input_guid[16] = UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; static int uvc_entity_match_guid(const struct uvc_entity *entity, - const __u8 guid[16]) + const u8 guid[16]) { switch (UVC_ENTITY_TYPE(entity)) { case UVC_ITT_CAMERA: @@ -857,7 +857,7 @@ static int uvc_entity_match_guid(const struct uvc_entity *entity, * UVC Controls */ -static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, +static void __uvc_find_control(struct uvc_entity *entity, u32 v4l2_id, struct uvc_control_mapping **mapping, struct uvc_control **control, int next) { @@ -890,7 +890,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, } static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, - __u32 v4l2_id, struct uvc_control_mapping **mapping) + u32 v4l2_id, struct uvc_control_mapping **mapping) { struct uvc_control *ctrl = NULL; struct uvc_entity *entity; @@ -1019,10 +1019,10 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, struct uvc_menu_info *menu; unsigned int i; - memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); + memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl)); v4l2_ctrl->id = mapping->id; v4l2_ctrl->type = mapping->v4l2_type; - strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); + strlcpy(v4l2_ctrl->name, mapping->name, sizeof(v4l2_ctrl->name)); v4l2_ctrl->flags = 0; if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) @@ -1182,7 +1182,7 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, } } - strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); + strlcpy(query_menu->name, menu_info->name, sizeof(query_menu->name)); done: mutex_unlock(&chain->ctrl_mutex); @@ -1590,6 +1590,36 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, * Dynamic controls */ +/* + * Retrieve flags for a given control + */ +static int uvc_ctrl_get_flags(struct uvc_device *dev, + const struct uvc_control *ctrl, + struct uvc_control_info *info) +{ + u8 *data; + int ret; + + data = kmalloc(1, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, + info->selector, data, 1); + if (!ret) + info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX + | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF + | (data[0] & UVC_CONTROL_CAP_GET ? + UVC_CTRL_FLAG_GET_CUR : 0) + | (data[0] & UVC_CONTROL_CAP_SET ? + UVC_CTRL_FLAG_SET_CUR : 0) + | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? + UVC_CTRL_FLAG_AUTO_UPDATE : 0); + + kfree(data); + return ret; +} + static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev, const struct uvc_control *ctrl, struct uvc_control_info *info) { @@ -1659,25 +1689,14 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev, info->size = le16_to_cpup((__le16 *)data); - /* Query the control information (GET_INFO) */ - ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, - info->selector, data, 1); + ret = uvc_ctrl_get_flags(dev, ctrl, info); if (ret < 0) { uvc_trace(UVC_TRACE_CONTROL, - "GET_INFO failed on control %pUl/%u (%d).\n", + "Failed to get flags for control %pUl/%u (%d).\n", info->entity, info->selector, ret); goto done; } - info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX - | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF - | (data[0] & UVC_CONTROL_CAP_GET ? - UVC_CTRL_FLAG_GET_CUR : 0) - | (data[0] & UVC_CONTROL_CAP_SET ? - UVC_CTRL_FLAG_SET_CUR : 0) - | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? - UVC_CTRL_FLAG_AUTO_UPDATE : 0); - uvc_ctrl_fixup_xu_info(dev, ctrl, info); uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " @@ -1723,9 +1742,9 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_entity *entity; struct uvc_control *ctrl; unsigned int i, found = 0; - __u32 reqflags; - __u16 size; - __u8 *data = NULL; + u32 reqflags; + u16 size; + u8 *data = NULL; int ret; /* Find the extension unit. */ @@ -1902,6 +1921,13 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl, goto done; } + /* + * Retrieve control flags from the device. Ignore errors and work with + * default flag values from the uvc_ctrl array when the device doesn't + * properly implement GET_INFO on standard controls. + */ + uvc_ctrl_get_flags(dev, ctrl, &ctrl->info); + ctrl->initialized = 1; uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " @@ -2150,7 +2176,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev) list_for_each_entry(entity, &dev->entities, list) { struct uvc_control *ctrl; unsigned int bControlSize = 0, ncontrols; - __u8 *bmControls = NULL; + u8 *bmControls = NULL; if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { bmControls = entity->extension.bmControls; diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index fd387bf3f02d..2469b49b2b30 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -216,7 +216,7 @@ static struct uvc_format_desc uvc_fmts[] = { */ struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, - __u8 epaddr) + u8 epaddr) { struct usb_host_endpoint *ep; unsigned int i; @@ -230,7 +230,7 @@ struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, return NULL; } -static struct uvc_format_desc *uvc_format_by_guid(const __u8 guid[16]) +static struct uvc_format_desc *uvc_format_by_guid(const u8 guid[16]) { unsigned int len = ARRAY_SIZE(uvc_fmts); unsigned int i; @@ -243,9 +243,9 @@ static struct uvc_format_desc *uvc_format_by_guid(const __u8 guid[16]) return NULL; } -static __u32 uvc_colorspace(const __u8 primaries) +static u32 uvc_colorspace(const u8 primaries) { - static const __u8 colorprimaries[] = { + static const u8 colorprimaries[] = { 0, V4L2_COLORSPACE_SRGB, V4L2_COLORSPACE_470_SYSTEM_M, @@ -267,14 +267,14 @@ static __u32 uvc_colorspace(const __u8 primaries) * continued fraction decomposition. Using 8 and 333 for n_terms and threshold * respectively seems to give nice results. */ -void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, +void uvc_simplify_fraction(u32 *numerator, u32 *denominator, unsigned int n_terms, unsigned int threshold) { - uint32_t *an; - uint32_t x, y, r; + u32 *an; + u32 x, y, r; unsigned int i, n; - an = kmalloc(n_terms * sizeof *an, GFP_KERNEL); + an = kmalloc_array(n_terms, sizeof(*an), GFP_KERNEL); if (an == NULL) return; @@ -318,21 +318,21 @@ void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, * to compute numerator / denominator * 10000000 using 32 bit fixed point * arithmetic only. */ -uint32_t uvc_fraction_to_interval(uint32_t numerator, uint32_t denominator) +u32 uvc_fraction_to_interval(u32 numerator, u32 denominator) { - uint32_t multiplier; + u32 multiplier; /* Saturate the result if the operation would overflow. */ if (denominator == 0 || - numerator/denominator >= ((uint32_t)-1)/10000000) - return (uint32_t)-1; + numerator/denominator >= ((u32)-1)/10000000) + return (u32)-1; /* Divide both the denominator and the multiplier by two until * numerator * multiplier doesn't overflow. If anyone knows a better * algorithm please let me know. */ multiplier = 10000000; - while (numerator > ((uint32_t)-1)/multiplier) { + while (numerator > ((u32)-1)/multiplier) { multiplier /= 2; denominator /= 2; } @@ -391,7 +391,7 @@ static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id) static int uvc_parse_format(struct uvc_device *dev, struct uvc_streaming *streaming, struct uvc_format *format, - __u32 **intervals, unsigned char *buffer, int buflen) + u32 **intervals, unsigned char *buffer, int buflen) { struct usb_interface *intf = streaming->intf; struct usb_host_interface *alts = intf->cur_altsetting; @@ -401,7 +401,7 @@ static int uvc_parse_format(struct uvc_device *dev, unsigned int width_multiplier = 1; unsigned int interval; unsigned int i, n; - __u8 ftype; + u8 ftype; format->type = buffer[2]; format->index = buffer[3]; @@ -423,7 +423,7 @@ static int uvc_parse_format(struct uvc_device *dev, if (fmtdesc != NULL) { strlcpy(format->name, fmtdesc->name, - sizeof format->name); + sizeof(format->name)); format->fcc = fmtdesc->fcc; } else { uvc_printk(KERN_INFO, "Unknown video format %pUl\n", @@ -466,7 +466,7 @@ static int uvc_parse_format(struct uvc_device *dev, return -EINVAL; } - strlcpy(format->name, "MJPEG", sizeof format->name); + strlcpy(format->name, "MJPEG", sizeof(format->name)); format->fcc = V4L2_PIX_FMT_MJPEG; format->flags = UVC_FMT_FLAG_COMPRESSED; format->bpp = 0; @@ -484,13 +484,13 @@ static int uvc_parse_format(struct uvc_device *dev, switch (buffer[8] & 0x7f) { case 0: - strlcpy(format->name, "SD-DV", sizeof format->name); + strlcpy(format->name, "SD-DV", sizeof(format->name)); break; case 1: - strlcpy(format->name, "SDL-DV", sizeof format->name); + strlcpy(format->name, "SDL-DV", sizeof(format->name)); break; case 2: - strlcpy(format->name, "HD-DV", sizeof format->name); + strlcpy(format->name, "HD-DV", sizeof(format->name)); break; default: uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " @@ -501,7 +501,7 @@ static int uvc_parse_format(struct uvc_device *dev, } strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz", - sizeof format->name); + sizeof(format->name)); format->fcc = V4L2_PIX_FMT_DV; format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM; @@ -510,7 +510,7 @@ static int uvc_parse_format(struct uvc_device *dev, /* Create a dummy frame descriptor. */ frame = &format->frame[0]; - memset(&format->frame[0], 0, sizeof format->frame[0]); + memset(&format->frame[0], 0, sizeof(format->frame[0])); frame->bFrameIntervalType = 1; frame->dwDefaultFrameInterval = 1; frame->dwFrameInterval = *intervals; @@ -658,8 +658,8 @@ static int uvc_parse_streaming(struct uvc_device *dev, int _buflen, buflen = alts->extralen; unsigned int nformats = 0, nframes = 0, nintervals = 0; unsigned int size, i, n, p; - __u32 *interval; - __u16 psize; + u32 *interval; + u16 psize; int ret = -EINVAL; if (intf->cur_altsetting->desc.bInterfaceSubClass @@ -677,7 +677,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, return -EINVAL; } - streaming = kzalloc(sizeof *streaming, GFP_KERNEL); + streaming = kzalloc(sizeof(*streaming), GFP_KERNEL); if (streaming == NULL) { usb_driver_release_interface(&uvc_driver.driver, intf); return -EINVAL; @@ -827,8 +827,8 @@ static int uvc_parse_streaming(struct uvc_device *dev, goto error; } - size = nformats * sizeof *format + nframes * sizeof *frame - + nintervals * sizeof *interval; + size = nformats * sizeof(*format) + nframes * sizeof(*frame) + + nintervals * sizeof(*interval); format = kzalloc(size, GFP_KERNEL); if (format == NULL) { ret = -ENOMEM; @@ -836,7 +836,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, } frame = (struct uvc_frame *)&format[nformats]; - interval = (__u32 *)&frame[nframes]; + interval = (u32 *)&frame[nframes]; streaming->format = format; streaming->nformats = nformats; @@ -930,7 +930,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id, entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE; entity->bNrInPins = num_inputs; - entity->baSourceID = (__u8 *)(&entity->pads[num_pads]); + entity->baSourceID = (u8 *)(&entity->pads[num_pads]); return entity; } @@ -995,14 +995,14 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, unit->extension.bNumControls = buffer[20]; memcpy(unit->baSourceID, &buffer[22], p); unit->extension.bControlSize = buffer[22+p]; - unit->extension.bmControls = (__u8 *)unit + sizeof(*unit); - unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit) + unit->extension.bmControls = (u8 *)unit + sizeof(*unit); + unit->extension.bmControlsType = (u8 *)unit + sizeof(*unit) + n; memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); if (buffer[24+p+2*n] != 0) usb_string(udev, buffer[24+p+2*n], unit->name, - sizeof unit->name); + sizeof(unit->name)); else sprintf(unit->name, "Extension %u", buffer[3]); @@ -1022,7 +1022,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, struct usb_interface *intf; struct usb_host_interface *alts = dev->intf->cur_altsetting; unsigned int i, n, p, len; - __u16 type; + u16 type; switch (buffer[2]) { case UVC_VC_HEADER: @@ -1101,7 +1101,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { term->camera.bControlSize = n; - term->camera.bmControls = (__u8 *)term + sizeof *term; + term->camera.bmControls = (u8 *)term + sizeof(*term); term->camera.wObjectiveFocalLengthMin = get_unaligned_le16(&buffer[8]); term->camera.wObjectiveFocalLengthMax = @@ -1112,17 +1112,17 @@ static int uvc_parse_standard_control(struct uvc_device *dev, } else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) { term->media.bControlSize = n; - term->media.bmControls = (__u8 *)term + sizeof *term; + term->media.bmControls = (u8 *)term + sizeof(*term); term->media.bTransportModeSize = p; - term->media.bmTransportModes = (__u8 *)term - + sizeof *term + n; + term->media.bmTransportModes = (u8 *)term + + sizeof(*term) + n; memcpy(term->media.bmControls, &buffer[9], n); memcpy(term->media.bmTransportModes, &buffer[10+n], p); } if (buffer[7] != 0) usb_string(udev, buffer[7], term->name, - sizeof term->name); + sizeof(term->name)); else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) sprintf(term->name, "Camera %u", buffer[3]); else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) @@ -1162,7 +1162,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, if (buffer[8] != 0) usb_string(udev, buffer[8], term->name, - sizeof term->name); + sizeof(term->name)); else sprintf(term->name, "Output %u", buffer[3]); @@ -1187,7 +1187,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, if (buffer[5+p] != 0) usb_string(udev, buffer[5+p], unit->name, - sizeof unit->name); + sizeof(unit->name)); else sprintf(unit->name, "Selector %u", buffer[3]); @@ -1213,14 +1213,14 @@ static int uvc_parse_standard_control(struct uvc_device *dev, unit->processing.wMaxMultiplier = get_unaligned_le16(&buffer[5]); unit->processing.bControlSize = buffer[7]; - unit->processing.bmControls = (__u8 *)unit + sizeof *unit; + unit->processing.bmControls = (u8 *)unit + sizeof(*unit); memcpy(unit->processing.bmControls, &buffer[8], n); if (dev->uvc_version >= 0x0110) unit->processing.bmVideoStandards = buffer[9+n]; if (buffer[8+n] != 0) usb_string(udev, buffer[8+n], unit->name, - sizeof unit->name); + sizeof(unit->name)); else sprintf(unit->name, "Processing %u", buffer[3]); @@ -1246,12 +1246,12 @@ static int uvc_parse_standard_control(struct uvc_device *dev, unit->extension.bNumControls = buffer[20]; memcpy(unit->baSourceID, &buffer[22], p); unit->extension.bControlSize = buffer[22+p]; - unit->extension.bmControls = (__u8 *)unit + sizeof *unit; + unit->extension.bmControls = (u8 *)unit + sizeof(*unit); memcpy(unit->extension.bmControls, &buffer[23+p], n); if (buffer[23+p+n] != 0) usb_string(udev, buffer[23+p+n], unit->name, - sizeof unit->name); + sizeof(unit->name)); else sprintf(unit->name, "Extension %u", buffer[3]); @@ -1936,7 +1936,7 @@ int uvc_register_video_device(struct uvc_device *dev, break; } - strlcpy(vdev->name, dev->name, sizeof vdev->name); + strlcpy(vdev->name, dev->name, sizeof(vdev->name)); /* * Set the driver data before calling video_register_device, otherwise @@ -2070,7 +2070,8 @@ static int uvc_probe(struct usb_interface *intf, udev->devpath); /* Allocate memory for the device and initialize it. */ - if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL) + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) return -ENOMEM; INIT_LIST_HEAD(&dev->entities); @@ -2089,9 +2090,9 @@ static int uvc_probe(struct usb_interface *intf, dev->meta_format = info->meta_format; if (udev->product != NULL) - strlcpy(dev->name, udev->product, sizeof dev->name); + strlcpy(dev->name, udev->product, sizeof(dev->name)); else - snprintf(dev->name, sizeof dev->name, + snprintf(dev->name, sizeof(dev->name), "UVC Camera (%04x:%04x)", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c index 5059fbf41020..81e6f2187bfb 100644 --- a/drivers/media/usb/uvc/uvc_isight.c +++ b/drivers/media/usb/uvc/uvc_isight.c @@ -37,16 +37,16 @@ */ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, - const __u8 *data, unsigned int len) + const u8 *data, unsigned int len) { - static const __u8 hdr[] = { + static const u8 hdr[] = { 0x11, 0x22, 0x33, 0x44, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce }; unsigned int maxlen, nbytes; - __u8 *mem; + u8 *mem; int is_header = 0; if (buf == NULL) diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c index 1ef20e74b7ac..7b710410584a 100644 --- a/drivers/media/usb/uvc/uvc_status.c +++ b/drivers/media/usb/uvc/uvc_status.c @@ -78,7 +78,7 @@ static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, /* -------------------------------------------------------------------------- * Status interrupt endpoint */ -static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) +static void uvc_event_streaming(struct uvc_device *dev, u8 *data, int len) { if (len < 3) { uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " @@ -99,7 +99,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) } } -static void uvc_event_control(struct uvc_device *dev, __u8 *data, int len) +static void uvc_event_control(struct uvc_device *dev, u8 *data, int len) { char *attrs[3] = { "value", "info", "failure" }; diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index a13ad4e178be..bd32914259ae 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -40,13 +40,13 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, unsigned int size; int ret; - map = kzalloc(sizeof *map, GFP_KERNEL); + map = kzalloc(sizeof(*map), GFP_KERNEL); if (map == NULL) return -ENOMEM; map->id = xmap->id; - memcpy(map->name, xmap->name, sizeof map->name); - memcpy(map->entity, xmap->entity, sizeof map->entity); + memcpy(map->name, xmap->name, sizeof(map->name)); + memcpy(map->entity, xmap->entity, sizeof(map->entity)); map->selector = xmap->selector; map->size = xmap->size; map->offset = xmap->offset; @@ -105,12 +105,12 @@ free_map: * the Video Probe and Commit negotiation, but some hardware don't implement * that feature. */ -static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) +static u32 uvc_try_frame_interval(struct uvc_frame *frame, u32 interval) { unsigned int i; if (frame->bFrameIntervalType) { - __u32 best = -1, dist; + u32 best = -1, dist; for (i = 0; i < frame->bFrameIntervalType; ++i) { dist = interval > frame->dwFrameInterval[i] @@ -125,9 +125,9 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) interval = frame->dwFrameInterval[i-1]; } else { - const __u32 min = frame->dwFrameInterval[0]; - const __u32 max = frame->dwFrameInterval[1]; - const __u32 step = frame->dwFrameInterval[2]; + const u32 min = frame->dwFrameInterval[0]; + const u32 max = frame->dwFrameInterval[1]; + const u32 step = frame->dwFrameInterval[2]; interval = min + (interval - min + step/2) / step * step; if (interval > max) @@ -137,7 +137,7 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) return interval; } -static __u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format, +static u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format, const struct uvc_frame *frame) { switch (format->fcc) { @@ -158,17 +158,17 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, { struct uvc_format *format = NULL; struct uvc_frame *frame = NULL; - __u16 rw, rh; + u16 rw, rh; unsigned int d, maxd; unsigned int i; - __u32 interval; + u32 interval; int ret = 0; - __u8 *fcc; + u8 *fcc; if (fmt->type != stream->type) return -EINVAL; - fcc = (__u8 *)&fmt->fmt.pix.pixelformat; + fcc = (u8 *)&fmt->fmt.pix.pixelformat; uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n", fmt->fmt.pix.pixelformat, fcc[0], fcc[1], fcc[2], fcc[3], @@ -197,8 +197,8 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, maxd = (unsigned int)-1; for (i = 0; i < format->nframes; ++i) { - __u16 w = format->frame[i].wWidth; - __u16 h = format->frame[i].wHeight; + u16 w = format->frame[i].wWidth; + u16 h = format->frame[i].wHeight; d = min(w, rw) * min(h, rh); d = w*h + rw*rh - 2*d; @@ -224,7 +224,7 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, (100000000/interval)%10); /* Set the format index, frame index and frame interval. */ - memset(probe, 0, sizeof *probe); + memset(probe, 0, sizeof(*probe)); probe->bmHint = 1; /* dwFrameInterval */ probe->bFormatIndex = format->index; probe->bFrameIndex = frame->bFrameIndex; @@ -336,7 +336,7 @@ done: static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, struct v4l2_streamparm *parm) { - uint32_t numerator, denominator; + u32 numerator, denominator; if (parm->type != stream->type) return -EINVAL; @@ -348,7 +348,7 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, denominator = 10000000; uvc_simplify_fraction(&numerator, &denominator, 8, 333); - memset(parm, 0, sizeof *parm); + memset(parm, 0, sizeof(*parm)); parm->type = stream->type; if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { @@ -373,7 +373,10 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, { struct uvc_streaming_control probe; struct v4l2_fract timeperframe; - uint32_t interval; + struct uvc_format *format; + struct uvc_frame *frame; + u32 interval, maxd; + unsigned int i; int ret; if (parm->type != stream->type) @@ -396,9 +399,33 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, return -EBUSY; } + format = stream->cur_format; + frame = stream->cur_frame; probe = stream->ctrl; - probe.dwFrameInterval = - uvc_try_frame_interval(stream->cur_frame, interval); + probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); + maxd = abs((s32)probe.dwFrameInterval - interval); + + /* Try frames with matching size to find the best frame interval. */ + for (i = 0; i < format->nframes && maxd != 0; i++) { + u32 d, ival; + + if (&format->frame[i] == stream->cur_frame) + continue; + + if (format->frame[i].wWidth != stream->cur_frame->wWidth || + format->frame[i].wHeight != stream->cur_frame->wHeight) + continue; + + ival = uvc_try_frame_interval(&format->frame[i], interval); + d = abs((s32)ival - interval); + if (d >= maxd) + continue; + + frame = &format->frame[i]; + probe.bFrameIndex = frame->bFrameIndex; + probe.dwFrameInterval = ival; + maxd = d; + } /* Probe the device with the new settings. */ ret = uvc_probe_video(stream, &probe); @@ -408,6 +435,7 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, } stream->ctrl = probe; + stream->cur_frame = frame; mutex_unlock(&stream->mutex); /* Return the actual frame period. */ @@ -498,7 +526,7 @@ static int uvc_v4l2_open(struct file *file) return ret; /* Create the device handle. */ - handle = kzalloc(sizeof *handle, GFP_KERNEL); + handle = kzalloc(sizeof(*handle), GFP_KERNEL); if (handle == NULL) { usb_autopm_put_interface(stream->dev->intf); return -ENOMEM; @@ -577,7 +605,7 @@ static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream, { struct uvc_format *format; enum v4l2_buf_type type = fmt->type; - __u32 index = fmt->index; + u32 index = fmt->index; if (fmt->type != stream->type || fmt->index >= stream->nformats) return -EINVAL; @@ -1145,8 +1173,9 @@ static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, struct uvc_fh *handle = fh; struct uvc_streaming *stream = handle->stream; struct uvc_format *format = NULL; - struct uvc_frame *frame; - int i; + struct uvc_frame *frame = NULL; + unsigned int index; + unsigned int i; /* Look for the given pixel format */ for (i = 0; i < stream->nformats; i++) { @@ -1158,10 +1187,20 @@ static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, if (format == NULL) return -EINVAL; - if (fsize->index >= format->nframes) + /* Skip duplicate frame sizes */ + for (i = 0, index = 0; i < format->nframes; i++) { + if (frame && frame->wWidth == format->frame[i].wWidth && + frame->wHeight == format->frame[i].wHeight) + continue; + frame = &format->frame[i]; + if (index == fsize->index) + break; + index++; + } + + if (i == format->nframes) return -EINVAL; - frame = &format->frame[fsize->index]; fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; fsize->discrete.width = frame->wWidth; fsize->discrete.height = frame->wHeight; @@ -1175,7 +1214,9 @@ static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, struct uvc_streaming *stream = handle->stream; struct uvc_format *format = NULL; struct uvc_frame *frame = NULL; - int i; + unsigned int nintervals; + unsigned int index; + unsigned int i; /* Look for the given pixel format and frame size */ for (i = 0; i < stream->nformats; i++) { @@ -1187,30 +1228,28 @@ static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, if (format == NULL) return -EINVAL; + index = fival->index; for (i = 0; i < format->nframes; i++) { if (format->frame[i].wWidth == fival->width && format->frame[i].wHeight == fival->height) { frame = &format->frame[i]; - break; + nintervals = frame->bFrameIntervalType ?: 1; + if (index < nintervals) + break; + index -= nintervals; } } - if (frame == NULL) + if (i == format->nframes) return -EINVAL; if (frame->bFrameIntervalType) { - if (fival->index >= frame->bFrameIntervalType) - return -EINVAL; - fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; fival->discrete.numerator = - frame->dwFrameInterval[fival->index]; + frame->dwFrameInterval[index]; fival->discrete.denominator = 10000000; uvc_simplify_fraction(&fival->discrete.numerator, &fival->discrete.denominator, 8, 333); } else { - if (fival->index) - return -EINVAL; - fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; fival->stepwise.min.numerator = frame->dwFrameInterval[0]; fival->stepwise.min.denominator = 10000000; @@ -1261,20 +1300,20 @@ static long uvc_ioctl_default(struct file *file, void *fh, bool valid_prio, #ifdef CONFIG_COMPAT struct uvc_xu_control_mapping32 { - __u32 id; - __u8 name[32]; - __u8 entity[16]; - __u8 selector; + u32 id; + u8 name[32]; + u8 entity[16]; + u8 selector; - __u8 size; - __u8 offset; - __u32 v4l2_type; - __u32 data_type; + u8 size; + u8 offset; + u32 v4l2_type; + u32 data_type; compat_caddr_t menu_info; - __u32 menu_count; + u32 menu_count; - __u32 reserved[4]; + u32 reserved[4]; }; static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, @@ -1310,10 +1349,10 @@ static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp, } struct uvc_xu_control_query32 { - __u8 unit; - __u8 selector; - __u8 query; - __u16 size; + u8 unit; + u8 selector; + u8 query; + u16 size; compat_caddr_t data; }; diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 5441553f74e1..aa0082fe5833 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -30,11 +30,11 @@ * UVC Controls */ -static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, - __u8 intfnum, __u8 cs, void *data, __u16 size, +static int __uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, + u8 intfnum, u8 cs, void *data, u16 size, int timeout) { - __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; + u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; unsigned int pipe; pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0) @@ -45,7 +45,7 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, unit << 8 | intfnum, data, size, timeout); } -static const char *uvc_query_name(__u8 query) +static const char *uvc_query_name(u8 query) { switch (query) { case UVC_SET_CUR: @@ -69,8 +69,8 @@ static const char *uvc_query_name(__u8 query) } } -int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, - __u8 intfnum, __u8 cs, void *data, __u16 size) +int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, + u8 intfnum, u8 cs, void *data, u16 size) { int ret; @@ -164,10 +164,10 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, } static int uvc_get_video_ctrl(struct uvc_streaming *stream, - struct uvc_streaming_control *ctrl, int probe, __u8 query) + struct uvc_streaming_control *ctrl, int probe, u8 query) { - __u8 *data; - __u16 size; + u8 *data; + u16 size; int ret; size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; @@ -191,7 +191,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non " "compliance - GET_MIN/MAX(PROBE) incorrectly " "supported. Enabling workaround.\n"); - memset(ctrl, 0, sizeof *ctrl); + memset(ctrl, 0, sizeof(*ctrl)); ctrl->wCompQuality = le16_to_cpup((__le16 *)data); ret = 0; goto out; @@ -254,8 +254,8 @@ out: static int uvc_set_video_ctrl(struct uvc_streaming *stream, struct uvc_streaming_control *ctrl, int probe) { - __u8 *data; - __u16 size; + u8 *data; + u16 size; int ret; size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; @@ -301,7 +301,7 @@ int uvc_probe_video(struct uvc_streaming *stream, struct uvc_streaming_control *probe) { struct uvc_streaming_control probe_min, probe_max; - __u16 bandwidth; + u16 bandwidth; unsigned int i; int ret; @@ -379,7 +379,7 @@ static inline ktime_t uvc_video_get_time(void) static void uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, - const __u8 *data, int len) + const u8 *data, int len) { struct uvc_clock_sample *sample; unsigned int header_size; @@ -705,7 +705,7 @@ done: */ static void uvc_video_stats_decode(struct uvc_streaming *stream, - const __u8 *data, int len) + const u8 *data, int len) { unsigned int header_size; bool has_pts = false; @@ -946,9 +946,9 @@ static void uvc_video_stats_stop(struct uvc_streaming *stream) * uvc_video_decode_end will never be called with a NULL buffer. */ static int uvc_video_decode_start(struct uvc_streaming *stream, - struct uvc_buffer *buf, const __u8 *data, int len) + struct uvc_buffer *buf, const u8 *data, int len) { - __u8 fid; + u8 fid; /* Sanity checks: * - packet must be at least 2 bytes long @@ -1009,7 +1009,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, buf->buf.field = V4L2_FIELD_NONE; buf->buf.sequence = stream->sequence; - buf->buf.vb2_buf.timestamp = uvc_video_get_time(); + buf->buf.vb2_buf.timestamp = ktime_to_ns(uvc_video_get_time()); /* TODO: Handle PTS and SCR. */ buf->state = UVC_BUF_STATE_ACTIVE; @@ -1043,7 +1043,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, } static void uvc_video_decode_data(struct uvc_streaming *stream, - struct uvc_buffer *buf, const __u8 *data, int len) + struct uvc_buffer *buf, const u8 *data, int len) { unsigned int maxlen, nbytes; void *mem; @@ -1067,7 +1067,7 @@ static void uvc_video_decode_data(struct uvc_streaming *stream, } static void uvc_video_decode_end(struct uvc_streaming *stream, - struct uvc_buffer *buf, const __u8 *data, int len) + struct uvc_buffer *buf, const u8 *data, int len) { /* Mark the buffer as done if the EOF marker is set. */ if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) { @@ -1092,7 +1092,7 @@ static void uvc_video_decode_end(struct uvc_streaming *stream, * video buffer to the transfer buffer. */ static int uvc_video_encode_header(struct uvc_streaming *stream, - struct uvc_buffer *buf, __u8 *data, int len) + struct uvc_buffer *buf, u8 *data, int len) { data[0] = 2; /* Header length */ data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF @@ -1101,7 +1101,7 @@ static int uvc_video_encode_header(struct uvc_streaming *stream, } static int uvc_video_encode_data(struct uvc_streaming *stream, - struct uvc_buffer *buf, __u8 *data, int len) + struct uvc_buffer *buf, u8 *data, int len) { struct uvc_video_queue *queue = &stream->queue; unsigned int nbytes; @@ -1191,7 +1191,8 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream, uvc_trace(UVC_TRACE_FRAME, "%s(): t-sys %lluns, SOF %u, len %u, flags 0x%x, PTS %u, STC %u frame SOF %u\n", - __func__, time, meta->sof, meta->length, meta->flags, + __func__, ktime_to_ns(time), meta->sof, meta->length, + meta->flags, has_pts ? *(u32 *)meta->buf : 0, has_scr ? *(u32 *)scr : 0, has_scr ? *(u32 *)(scr + 4) & 0x7ff : 0); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index d9e7c70788d0..be5cf179228b 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -208,60 +208,60 @@ struct uvc_device; struct uvc_control_info { struct list_head mappings; - __u8 entity[16]; - __u8 index; /* Bit index in bmControls */ - __u8 selector; + u8 entity[16]; + u8 index; /* Bit index in bmControls */ + u8 selector; - __u16 size; - __u32 flags; + u16 size; + u32 flags; }; struct uvc_control_mapping { struct list_head list; struct list_head ev_subs; - __u32 id; - __u8 name[32]; - __u8 entity[16]; - __u8 selector; + u32 id; + u8 name[32]; + u8 entity[16]; + u8 selector; - __u8 size; - __u8 offset; + u8 size; + u8 offset; enum v4l2_ctrl_type v4l2_type; - __u32 data_type; + u32 data_type; struct uvc_menu_info *menu_info; - __u32 menu_count; + u32 menu_count; - __u32 master_id; - __s32 master_manual; - __u32 slave_ids[2]; + u32 master_id; + s32 master_manual; + u32 slave_ids[2]; - __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query, - const __u8 *data); - void (*set) (struct uvc_control_mapping *mapping, __s32 value, - __u8 *data); + s32 (*get)(struct uvc_control_mapping *mapping, u8 query, + const u8 *data); + void (*set)(struct uvc_control_mapping *mapping, s32 value, + u8 *data); }; struct uvc_control { struct uvc_entity *entity; struct uvc_control_info info; - __u8 index; /* Used to match the uvc_control entry with a + u8 index; /* Used to match the uvc_control entry with a uvc_control_info. */ - __u8 dirty:1, - loaded:1, - modified:1, - cached:1, - initialized:1; + u8 dirty:1, + loaded:1, + modified:1, + cached:1, + initialized:1; - __u8 *uvc_data; + u8 *uvc_data; }; struct uvc_format_desc { char *name; - __u8 guid[16]; - __u32 fcc; + u8 guid[16]; + u32 fcc; }; /* The term 'entity' refers to both UVC units and UVC terminals. @@ -287,8 +287,8 @@ struct uvc_entity { * chain. */ unsigned int flags; - __u8 id; - __u16 type; + u8 id; + u16 type; char name[64]; /* Media controller-related fields. */ @@ -300,69 +300,69 @@ struct uvc_entity { union { struct { - __u16 wObjectiveFocalLengthMin; - __u16 wObjectiveFocalLengthMax; - __u16 wOcularFocalLength; - __u8 bControlSize; - __u8 *bmControls; + u16 wObjectiveFocalLengthMin; + u16 wObjectiveFocalLengthMax; + u16 wOcularFocalLength; + u8 bControlSize; + u8 *bmControls; } camera; struct { - __u8 bControlSize; - __u8 *bmControls; - __u8 bTransportModeSize; - __u8 *bmTransportModes; + u8 bControlSize; + u8 *bmControls; + u8 bTransportModeSize; + u8 *bmTransportModes; } media; struct { } output; struct { - __u16 wMaxMultiplier; - __u8 bControlSize; - __u8 *bmControls; - __u8 bmVideoStandards; + u16 wMaxMultiplier; + u8 bControlSize; + u8 *bmControls; + u8 bmVideoStandards; } processing; struct { } selector; struct { - __u8 guidExtensionCode[16]; - __u8 bNumControls; - __u8 bControlSize; - __u8 *bmControls; - __u8 *bmControlsType; + u8 guidExtensionCode[16]; + u8 bNumControls; + u8 bControlSize; + u8 *bmControls; + u8 *bmControlsType; } extension; }; - __u8 bNrInPins; - __u8 *baSourceID; + u8 bNrInPins; + u8 *baSourceID; unsigned int ncontrols; struct uvc_control *controls; }; struct uvc_frame { - __u8 bFrameIndex; - __u8 bmCapabilities; - __u16 wWidth; - __u16 wHeight; - __u32 dwMinBitRate; - __u32 dwMaxBitRate; - __u32 dwMaxVideoFrameBufferSize; - __u8 bFrameIntervalType; - __u32 dwDefaultFrameInterval; - __u32 *dwFrameInterval; + u8 bFrameIndex; + u8 bmCapabilities; + u16 wWidth; + u16 wHeight; + u32 dwMinBitRate; + u32 dwMaxBitRate; + u32 dwMaxVideoFrameBufferSize; + u8 bFrameIntervalType; + u32 dwDefaultFrameInterval; + u32 *dwFrameInterval; }; struct uvc_format { - __u8 type; - __u8 index; - __u8 bpp; - __u8 colorspace; - __u32 fcc; - __u32 flags; + u8 type; + u8 index; + u8 bpp; + u8 colorspace; + u32 fcc; + u32 flags; char name[32]; @@ -371,16 +371,16 @@ struct uvc_format { }; struct uvc_streaming_header { - __u8 bNumFormats; - __u8 bEndpointAddress; - __u8 bTerminalLink; - __u8 bControlSize; - __u8 *bmaControls; + u8 bNumFormats; + u8 bEndpointAddress; + u8 bTerminalLink; + u8 bControlSize; + u8 *bmaControls; /* The following fields are used by input headers only. */ - __u8 bmInfo; - __u8 bStillCaptureMethod; - __u8 bTriggerSupport; - __u8 bTriggerUsage; + u8 bmInfo; + u8 bStillCaptureMethod; + u8 bTriggerSupport; + u8 bTriggerUsage; }; enum uvc_buffer_state { @@ -490,7 +490,7 @@ struct uvc_streaming { struct usb_interface *intf; int intfnum; - __u16 maxpsize; + u16 maxpsize; struct uvc_streaming_header header; enum v4l2_buf_type type; @@ -517,16 +517,16 @@ struct uvc_streaming { struct { struct video_device vdev; struct uvc_video_queue queue; - __u32 format; + u32 format; } meta; /* Context data used by the bulk completion handler. */ struct { - __u8 header[256]; + u8 header[256]; unsigned int header_size; int skip_payload; - __u32 payload_size; - __u32 max_payload_size; + u32 payload_size; + u32 max_payload_size; } bulk; struct urb *urb[UVC_URBS]; @@ -534,8 +534,8 @@ struct uvc_streaming { dma_addr_t urb_dma[UVC_URBS]; unsigned int urb_size; - __u32 sequence; - __u8 last_fid; + u32 sequence; + u8 last_fid; /* debugfs */ struct dentry *debugfs_dir; @@ -570,8 +570,8 @@ struct uvc_device { struct usb_device *udev; struct usb_interface *intf; unsigned long warnings; - __u32 quirks; - __u32 meta_format; + u32 quirks; + u32 meta_format; int intfnum; char name[32]; @@ -584,8 +584,8 @@ struct uvc_device { struct media_device mdev; #endif struct v4l2_device vdev; - __u16 uvc_version; - __u32 clock_frequency; + u16 uvc_version; + u32 clock_frequency; struct list_head entities; struct list_head chains; @@ -597,7 +597,7 @@ struct uvc_device { /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; struct urb *int_urb; - __u8 *status; + u8 *status; struct input_dev *input; char input_phys[64]; }; @@ -667,40 +667,38 @@ extern unsigned int uvc_hw_timestamps_param; /* Core driver */ extern struct uvc_driver uvc_driver; -extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); +struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); /* Video buffers queue management. */ -extern int uvc_queue_init(struct uvc_video_queue *queue, - enum v4l2_buf_type type, int drop_corrupted); -extern void uvc_queue_release(struct uvc_video_queue *queue); -extern int uvc_request_buffers(struct uvc_video_queue *queue, - struct v4l2_requestbuffers *rb); -extern int uvc_query_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf); -extern int uvc_create_buffers(struct uvc_video_queue *queue, - struct v4l2_create_buffers *v4l2_cb); -extern int uvc_queue_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf); -extern int uvc_export_buffer(struct uvc_video_queue *queue, - struct v4l2_exportbuffer *exp); -extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf, int nonblocking); -extern int uvc_queue_streamon(struct uvc_video_queue *queue, - enum v4l2_buf_type type); -extern int uvc_queue_streamoff(struct uvc_video_queue *queue, - enum v4l2_buf_type type); -extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); -extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, - struct uvc_buffer *buf); -extern int uvc_queue_mmap(struct uvc_video_queue *queue, - struct vm_area_struct *vma); -extern __poll_t uvc_queue_poll(struct uvc_video_queue *queue, - struct file *file, poll_table *wait); +int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, + int drop_corrupted); +void uvc_queue_release(struct uvc_video_queue *queue); +int uvc_request_buffers(struct uvc_video_queue *queue, + struct v4l2_requestbuffers *rb); +int uvc_query_buffer(struct uvc_video_queue *queue, + struct v4l2_buffer *v4l2_buf); +int uvc_create_buffers(struct uvc_video_queue *queue, + struct v4l2_create_buffers *v4l2_cb); +int uvc_queue_buffer(struct uvc_video_queue *queue, + struct v4l2_buffer *v4l2_buf); +int uvc_export_buffer(struct uvc_video_queue *queue, + struct v4l2_exportbuffer *exp); +int uvc_dequeue_buffer(struct uvc_video_queue *queue, + struct v4l2_buffer *v4l2_buf, int nonblocking); +int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type); +int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type); +void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); +struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, + struct uvc_buffer *buf); +int uvc_queue_mmap(struct uvc_video_queue *queue, + struct vm_area_struct *vma); +__poll_t uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, + poll_table *wait); #ifndef CONFIG_MMU -extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, - unsigned long pgoff); +unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, + unsigned long pgoff); #endif -extern int uvc_queue_allocated(struct uvc_video_queue *queue); +int uvc_queue_allocated(struct uvc_video_queue *queue); static inline int uvc_queue_streaming(struct uvc_video_queue *queue) { return vb2_is_streaming(&queue->queue); @@ -711,18 +709,18 @@ extern const struct v4l2_ioctl_ops uvc_ioctl_ops; extern const struct v4l2_file_operations uvc_fops; /* Media controller */ -extern int uvc_mc_register_entities(struct uvc_video_chain *chain); -extern void uvc_mc_cleanup_entity(struct uvc_entity *entity); +int uvc_mc_register_entities(struct uvc_video_chain *chain); +void uvc_mc_cleanup_entity(struct uvc_entity *entity); /* Video */ -extern int uvc_video_init(struct uvc_streaming *stream); -extern int uvc_video_suspend(struct uvc_streaming *stream); -extern int uvc_video_resume(struct uvc_streaming *stream, int reset); -extern int uvc_video_enable(struct uvc_streaming *stream, int enable); -extern int uvc_probe_video(struct uvc_streaming *stream, - struct uvc_streaming_control *probe); -extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, - __u8 intfnum, __u8 cs, void *data, __u16 size); +int uvc_video_init(struct uvc_streaming *stream); +int uvc_video_suspend(struct uvc_streaming *stream); +int uvc_video_resume(struct uvc_streaming *stream, int reset); +int uvc_video_enable(struct uvc_streaming *stream, int enable); +int uvc_probe_video(struct uvc_streaming *stream, + struct uvc_streaming_control *probe); +int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, + u8 intfnum, u8 cs, void *data, u16 size); void uvc_video_clock_update(struct uvc_streaming *stream, struct vb2_v4l2_buffer *vbuf, struct uvc_buffer *buf); @@ -737,32 +735,32 @@ int uvc_register_video_device(struct uvc_device *dev, const struct v4l2_ioctl_ops *ioctl_ops); /* Status */ -extern int uvc_status_init(struct uvc_device *dev); -extern void uvc_status_cleanup(struct uvc_device *dev); -extern int uvc_status_start(struct uvc_device *dev, gfp_t flags); -extern void uvc_status_stop(struct uvc_device *dev); +int uvc_status_init(struct uvc_device *dev); +void uvc_status_cleanup(struct uvc_device *dev); +int uvc_status_start(struct uvc_device *dev, gfp_t flags); +void uvc_status_stop(struct uvc_device *dev); /* Controls */ extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops; -extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, - struct v4l2_queryctrl *v4l2_ctrl); -extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, - struct v4l2_querymenu *query_menu); - -extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, - const struct uvc_control_mapping *mapping); -extern int uvc_ctrl_init_device(struct uvc_device *dev); -extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); -extern int uvc_ctrl_restore_values(struct uvc_device *dev); - -extern int uvc_ctrl_begin(struct uvc_video_chain *chain); -extern int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, - const struct v4l2_ext_control *xctrls, - unsigned int xctrls_count); +int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, + struct v4l2_queryctrl *v4l2_ctrl); +int uvc_query_v4l2_menu(struct uvc_video_chain *chain, + struct v4l2_querymenu *query_menu); + +int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, + const struct uvc_control_mapping *mapping); +int uvc_ctrl_init_device(struct uvc_device *dev); +void uvc_ctrl_cleanup_device(struct uvc_device *dev); +int uvc_ctrl_restore_values(struct uvc_device *dev); + +int uvc_ctrl_begin(struct uvc_video_chain *chain); +int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, + const struct v4l2_ext_control *xctrls, + unsigned int xctrls_count); static inline int uvc_ctrl_commit(struct uvc_fh *handle, - const struct v4l2_ext_control *xctrls, - unsigned int xctrls_count) + const struct v4l2_ext_control *xctrls, + unsigned int xctrls_count) { return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count); } @@ -771,25 +769,23 @@ static inline int uvc_ctrl_rollback(struct uvc_fh *handle) return __uvc_ctrl_commit(handle, 1, NULL, 0); } -extern int uvc_ctrl_get(struct uvc_video_chain *chain, - struct v4l2_ext_control *xctrl); -extern int uvc_ctrl_set(struct uvc_video_chain *chain, - struct v4l2_ext_control *xctrl); +int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl); +int uvc_ctrl_set(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl); -extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain, - struct uvc_xu_control_query *xqry); +int uvc_xu_ctrl_query(struct uvc_video_chain *chain, + struct uvc_xu_control_query *xqry); /* Utility functions */ -extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, - unsigned int n_terms, unsigned int threshold); -extern uint32_t uvc_fraction_to_interval(uint32_t numerator, - uint32_t denominator); -extern struct usb_host_endpoint *uvc_find_endpoint( - struct usb_host_interface *alts, __u8 epaddr); +void uvc_simplify_fraction(u32 *numerator, u32 *denominator, + unsigned int n_terms, unsigned int threshold); +u32 uvc_fraction_to_interval(u32 numerator, u32 denominator); +struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, + u8 epaddr); /* Quirks support */ void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, - struct uvc_buffer *buf, struct uvc_buffer *meta_buf); + struct uvc_buffer *buf, + struct uvc_buffer *meta_buf); /* debugfs and statistics */ void uvc_debugfs_init(void); diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index 8b7c19943d46..b8886102c5ed 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -517,8 +517,7 @@ static void zr364xx_fillbuff(struct zr364xx_camera *cam, printk(KERN_ERR KBUILD_MODNAME ": =======no frame\n"); return; } - DBG("%s: Buffer 0x%08lx size= %d\n", __func__, - (unsigned long)vbuf, pos); + DBG("%s: Buffer %p size= %d\n", __func__, vbuf, pos); /* tell v4l buffer was filled */ buf->vb.field_count = cam->frame_count * 2; @@ -1277,7 +1276,7 @@ static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma) DBG("%s: cam == NULL\n", __func__); return -ENODEV; } - DBG("mmap called, vma=0x%08lx\n", (unsigned long)vma); + DBG("mmap called, vma=%p\n", vma); ret = videobuf_mmap_mapper(&cam->vb_vidq, vma); |