These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / media / pci / cx23885 / cx23885-dvb.c
index 745caab..c4307ad 100644 (file)
@@ -92,7 +92,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 /* ------------------------------------------------------------------ */
 
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
                           unsigned int *num_buffers, unsigned int *num_planes,
                           unsigned int sizes[], void *alloc_ctxs[])
 {
@@ -110,18 +110,20 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
 
 static int buffer_prepare(struct vb2_buffer *vb)
 {
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
        struct cx23885_buffer *buf =
-               container_of(vb, struct cx23885_buffer, vb);
+               container_of(vbuf, struct cx23885_buffer, vb);
 
        return cx23885_buf_prepare(buf, port);
 }
 
 static void buffer_finish(struct vb2_buffer *vb)
 {
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
        struct cx23885_dev *dev = port->dev;
-       struct cx23885_buffer *buf = container_of(vb,
+       struct cx23885_buffer *buf = container_of(vbuf,
                struct cx23885_buffer, vb);
 
        cx23885_free_buffer(dev, buf);
@@ -129,8 +131,9 @@ static void buffer_finish(struct vb2_buffer *vb)
 
 static void buffer_queue(struct vb2_buffer *vb)
 {
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
-       struct cx23885_buffer   *buf = container_of(vb,
+       struct cx23885_buffer   *buf = container_of(vbuf,
                struct cx23885_buffer, vb);
 
        cx23885_buf_queue(port, buf);
@@ -572,7 +575,8 @@ static struct stb6100_config prof_8000_stb6100_config = {
        .refclock = 27000000,
 };
 
-static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+static int p8000_set_voltage(struct dvb_frontend *fe,
+                            enum fe_sec_voltage voltage)
 {
        struct cx23885_tsport *port = fe->dvb->priv;
        struct cx23885_dev *dev = port->dev;
@@ -587,7 +591,7 @@ static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 }
 
 static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe,
-                                       fe_sec_voltage_t voltage)
+                                       enum fe_sec_voltage voltage)
 {
        struct cx23885_tsport *port = fe->dvb->priv;
        struct cx23885_dev *dev = port->dev;
@@ -616,7 +620,7 @@ static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe,
 }
 
 static int dvbsky_s952_portc_set_voltage(struct dvb_frontend *fe,
-                                       fe_sec_voltage_t voltage)
+                                       enum fe_sec_voltage voltage)
 {
        struct cx23885_tsport *port = fe->dvb->priv;
        struct cx23885_dev *dev = port->dev;
@@ -856,18 +860,12 @@ static struct mt2063_config terratec_mt2063_config[] = {
        },
 };
 
-static const struct tda10071_config hauppauge_tda10071_config = {
-       .demod_i2c_addr = 0x05,
-       .tuner_i2c_addr = 0x54,
+static const struct tda10071_platform_data hauppauge_tda10071_pdata = {
+       .clk = 40444000, /* 40.444 MHz */
        .i2c_wr_max = 64,
        .ts_mode = TDA10071_TS_SERIAL,
-       .spec_inv = 0,
-       .xtal = 40444000, /* 40.444 MHz */
        .pll_multiplier = 20,
-};
-
-static const struct a8293_config hauppauge_a8293_config = {
-       .i2c_addr = 0x0b,
+       .tuner_i2c_addr = 0x54,
 };
 
 static const struct si2165_config hauppauge_hvr4400_si2165_config = {
@@ -1190,8 +1188,10 @@ static int dvb_register(struct cx23885_tsport *port)
        struct i2c_board_info info;
        struct i2c_adapter *adapter;
        struct i2c_client *client_demod = NULL, *client_tuner = NULL;
+       struct i2c_client *client_sec = NULL;
        const struct m88ds3103_config *p_m88ds3103_config = NULL;
-       int (*p_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage) = NULL;
+       int (*p_set_voltage)(struct dvb_frontend *fe,
+                            enum fe_sec_voltage voltage) = NULL;
        int mfe_shared = 0; /* bus not shared by default */
        int ret;
 
@@ -1797,21 +1797,46 @@ static int dvb_register(struct cx23885_tsport *port)
 
                fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage;
                break;
-       case CX23885_BOARD_HAUPPAUGE_HVR4400:
+       case CX23885_BOARD_HAUPPAUGE_HVR4400: {
+               struct tda10071_platform_data tda10071_pdata = hauppauge_tda10071_pdata;
+               struct a8293_platform_data a8293_pdata = {};
+
                i2c_bus = &dev->i2c_bus[0];
                i2c_bus2 = &dev->i2c_bus[1];
                switch (port->nr) {
                /* port b */
                case 1:
-                       fe0->dvb.frontend = dvb_attach(tda10071_attach,
-                                               &hauppauge_tda10071_config,
-                                               &i2c_bus->i2c_adap);
-                       if (fe0->dvb.frontend == NULL)
-                               break;
-                       if (!dvb_attach(a8293_attach, fe0->dvb.frontend,
-                                       &i2c_bus->i2c_adap,
-                                       &hauppauge_a8293_config))
+                       /* attach demod + tuner combo */
+                       memset(&info, 0, sizeof(info));
+                       strlcpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE);
+                       info.addr = 0x05;
+                       info.platform_data = &tda10071_pdata;
+                       request_module("tda10071");
+                       client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
+                       if (!client_demod || !client_demod->dev.driver)
+                               goto frontend_detach;
+                       if (!try_module_get(client_demod->dev.driver->owner)) {
+                               i2c_unregister_device(client_demod);
+                               goto frontend_detach;
+                       }
+                       fe0->dvb.frontend = tda10071_pdata.get_dvb_frontend(client_demod);
+                       port->i2c_client_demod = client_demod;
+
+                       /* attach SEC */
+                       a8293_pdata.dvb_frontend = fe0->dvb.frontend;
+                       memset(&info, 0, sizeof(info));
+                       strlcpy(info.type, "a8293", I2C_NAME_SIZE);
+                       info.addr = 0x0b;
+                       info.platform_data = &a8293_pdata;
+                       request_module("a8293");
+                       client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info);
+                       if (!client_sec || !client_sec->dev.driver)
+                               goto frontend_detach;
+                       if (!try_module_get(client_sec->dev.driver->owner)) {
+                               i2c_unregister_device(client_sec);
                                goto frontend_detach;
+                       }
+                       port->i2c_client_sec = client_sec;
                        break;
                /* port c */
                case 2:
@@ -1829,17 +1854,46 @@ static int dvb_register(struct cx23885_tsport *port)
                        break;
                }
                break;
-       case CX23885_BOARD_HAUPPAUGE_STARBURST:
+       }
+       case CX23885_BOARD_HAUPPAUGE_STARBURST: {
+               struct tda10071_platform_data tda10071_pdata = hauppauge_tda10071_pdata;
+               struct a8293_platform_data a8293_pdata = {};
+
                i2c_bus = &dev->i2c_bus[0];
-               fe0->dvb.frontend = dvb_attach(tda10071_attach,
-                                               &hauppauge_tda10071_config,
-                                               &i2c_bus->i2c_adap);
-               if (fe0->dvb.frontend != NULL) {
-                       dvb_attach(a8293_attach, fe0->dvb.frontend,
-                                  &i2c_bus->i2c_adap,
-                                  &hauppauge_a8293_config);
+
+               /* attach demod + tuner combo */
+               memset(&info, 0, sizeof(info));
+               strlcpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE);
+               info.addr = 0x05;
+               info.platform_data = &tda10071_pdata;
+               request_module("tda10071");
+               client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
+               if (!client_demod || !client_demod->dev.driver)
+                       goto frontend_detach;
+               if (!try_module_get(client_demod->dev.driver->owner)) {
+                       i2c_unregister_device(client_demod);
+                       goto frontend_detach;
                }
+               fe0->dvb.frontend = tda10071_pdata.get_dvb_frontend(client_demod);
+               port->i2c_client_demod = client_demod;
+
+               /* attach SEC */
+               a8293_pdata.dvb_frontend = fe0->dvb.frontend;
+               memset(&info, 0, sizeof(info));
+               strlcpy(info.type, "a8293", I2C_NAME_SIZE);
+               info.addr = 0x0b;
+               info.platform_data = &a8293_pdata;
+               request_module("a8293");
+               client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info);
+               if (!client_sec || !client_sec->dev.driver)
+                       goto frontend_detach;
+               if (!try_module_get(client_sec->dev.driver->owner)) {
+                       i2c_unregister_device(client_sec);
+                       goto frontend_detach;
+               }
+               port->i2c_client_sec = client_sec;
                break;
+       }
        case CX23885_BOARD_DVBSKY_T9580:
        case CX23885_BOARD_DVBSKY_S950:
                i2c_bus = &dev->i2c_bus[0];
@@ -1857,6 +1911,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        /* attach tuner */
                        memset(&ts2020_config, 0, sizeof(ts2020_config));
                        ts2020_config.fe = fe0->dvb.frontend;
+                       ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
                        memset(&info, 0, sizeof(struct i2c_board_info));
                        strlcpy(info.type, "ts2020", I2C_NAME_SIZE);
                        info.addr = 0x60;
@@ -1912,6 +1967,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        /* attach tuner */
                        memset(&si2157_config, 0, sizeof(si2157_config));
                        si2157_config.fe = fe0->dvb.frontend;
+                       si2157_config.if_port = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
                        strlcpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x60;
@@ -1957,6 +2013,7 @@ static int dvb_register(struct cx23885_tsport *port)
                /* attach tuner */
                memset(&si2157_config, 0, sizeof(si2157_config));
                si2157_config.fe = fe0->dvb.frontend;
+               si2157_config.if_port = 1;
                memset(&info, 0, sizeof(struct i2c_board_info));
                strlcpy(info.type, "si2157", I2C_NAME_SIZE);
                info.addr = 0x60;
@@ -1986,6 +2043,7 @@ static int dvb_register(struct cx23885_tsport *port)
                /* attach tuner */
                memset(&ts2020_config, 0, sizeof(ts2020_config));
                ts2020_config.fe = fe0->dvb.frontend;
+               ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
                memset(&info, 0, sizeof(struct i2c_board_info));
                strlcpy(info.type, "ts2020", I2C_NAME_SIZE);
                info.addr = 0x60;
@@ -2031,6 +2089,7 @@ static int dvb_register(struct cx23885_tsport *port)
                /* attach tuner */
                memset(&ts2020_config, 0, sizeof(ts2020_config));
                ts2020_config.fe = fe0->dvb.frontend;
+               ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
                memset(&info, 0, sizeof(struct i2c_board_info));
                strlcpy(info.type, "ts2020", I2C_NAME_SIZE);
                info.addr = 0x60;
@@ -2093,6 +2152,7 @@ static int dvb_register(struct cx23885_tsport *port)
                /* attach tuner */
                memset(&si2157_config, 0, sizeof(si2157_config));
                si2157_config.fe = fe0->dvb.frontend;
+               si2157_config.if_port = 1;
                memset(&info, 0, sizeof(struct i2c_board_info));
                strlcpy(info.type, "si2157", I2C_NAME_SIZE);
                info.addr = 0x60;
@@ -2111,6 +2171,7 @@ static int dvb_register(struct cx23885_tsport *port)
        case CX23885_BOARD_HAUPPAUGE_HVR5525:
                switch (port->nr) {
                struct m88rs6000t_config m88rs6000t_config;
+               struct a8293_platform_data a8293_pdata = {};
 
                /* port b - satellite */
                case 1:
@@ -2122,10 +2183,20 @@ static int dvb_register(struct cx23885_tsport *port)
                                break;
 
                        /* attach SEC */
-                       if (!dvb_attach(a8293_attach, fe0->dvb.frontend,
-                                       &dev->i2c_bus[0].i2c_adap,
-                                       &hauppauge_a8293_config))
+                       a8293_pdata.dvb_frontend = fe0->dvb.frontend;
+                       memset(&info, 0, sizeof(info));
+                       strlcpy(info.type, "a8293", I2C_NAME_SIZE);
+                       info.addr = 0x0b;
+                       info.platform_data = &a8293_pdata;
+                       request_module("a8293");
+                       client_sec = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info);
+                       if (!client_sec || !client_sec->dev.driver)
+                               goto frontend_detach;
+                       if (!try_module_get(client_sec->dev.driver->owner)) {
+                               i2c_unregister_device(client_sec);
                                goto frontend_detach;
+                       }
+                       port->i2c_client_sec = client_sec;
 
                        /* attach tuner */
                        memset(&m88rs6000t_config, 0, sizeof(m88rs6000t_config));
@@ -2172,6 +2243,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        /* attach tuner */
                        memset(&si2157_config, 0, sizeof(si2157_config));
                        si2157_config.fe = fe0->dvb.frontend;
+                       si2157_config.if_port = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
                        strlcpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x60;
@@ -2238,6 +2310,14 @@ static int dvb_register(struct cx23885_tsport *port)
        return 0;
 
 frontend_detach:
+       /* remove I2C client for SEC */
+       client_sec = port->i2c_client_sec;
+       if (client_sec) {
+               module_put(client_sec->dev.driver->owner);
+               i2c_unregister_device(client_sec);
+               port->i2c_client_sec = NULL;
+       }
+
        /* remove I2C client for tuner */
        client_tuner = port->i2c_client_tuner;
        if (client_tuner) {
@@ -2339,6 +2419,13 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
                i2c_unregister_device(client);
        }
 
+       /* remove I2C client for SEC */
+       client = port->i2c_client_sec;
+       if (client) {
+               module_put(client->dev.driver->owner);
+               i2c_unregister_device(client);
+       }
+
        /* remove I2C client for tuner */
        client = port->i2c_client_tuner;
        if (client) {