summaryrefslogtreecommitdiffstats
path: root/drivers/media/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/au0828/Kconfig5
-rw-r--r--drivers/media/usb/au0828/au0828-video.c4
-rw-r--r--drivers/media/usb/cpia2/cpia2_usb.c3
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c87
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c389
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx.h3
-rw-r--r--drivers/media/usb/dvb-usb-v2/Kconfig3
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.c985
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.h20
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c24
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c141
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-audio.c116
-rw-r--r--drivers/media/usb/em28xx/em28xx-camera.c49
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c905
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c231
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c1015
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c173
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c172
-rw-r--r--drivers/media/usb/em28xx/em28xx-reg.h52
-rw-r--r--drivers/media/usb/em28xx/em28xx-v4l.h27
-rw-r--r--drivers/media/usb/em28xx/em28xx-vbi.c39
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c391
-rw-r--r--drivers/media/usb/em28xx/em28xx.h396
-rw-r--r--drivers/media/usb/go7007/snd-go7007.c2
-rw-r--r--drivers/media/usb/gspca/dtcs033.c6
-rw-r--r--drivers/media/usb/s2255/s2255drv.c12
-rw-r--r--drivers/media/usb/siano/smsusb.c4
-rw-r--r--drivers/media/usb/tm6000/tm6000-cards.c2
-rw-r--r--drivers/media/usb/tm6000/tm6000-video.c5
-rw-r--r--drivers/media/usb/usbtv/usbtv-core.c3
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c114
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c97
-rw-r--r--drivers/media/usb/uvc/uvc_isight.c6
-rw-r--r--drivers/media/usb/uvc/uvc_status.c4
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c141
-rw-r--r--drivers/media/usb/uvc/uvc_video.c47
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h320
-rw-r--r--drivers/media/usb/zr364xx/zr364xx.c5
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, &params);
+ dops->set_analog_params(dev->dvb->frontend[0], &params);
}
}
@@ -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, &regmap_bus, d, &regmap_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);