[media] rtl28xxu: switch SDR module to platform driver
authorAntti Palosaari <crope@iki.fi>
Tue, 16 Dec 2014 13:50:54 +0000 (10:50 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 3 Feb 2015 18:16:17 +0000 (16:16 -0200)
RTL2832 SDR module implements kernel platform driver. Change old
binding to that one.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.h

index c64b5ed60ab95dcbee00ee07fdbe78a854e2b9e2..c2d377fa193ac4c154e53d33fff1a45bab5ec952 100644 (file)
 
 #include "rtl28xxu.h"
 
-#ifdef CONFIG_MEDIA_ATTACH
-#define dvb_attach_sdr(FUNCTION, ARGS...) ({ \
-       void *__r = NULL; \
-       typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
-       if (__a) { \
-               __r = (void *) __a(ARGS); \
-               if (__r == NULL) \
-                       symbol_put(FUNCTION); \
-       } \
-       __r; \
-})
-
-#else
-#define dvb_attach_sdr(FUNCTION, ARGS...) ({ \
-       FUNCTION(ARGS); \
-})
-
-#endif
-
 static int rtl28xxu_disable_rc;
 module_param_named(disable_rc, rtl28xxu_disable_rc, int, 0644);
 MODULE_PARM_DESC(disable_rc, "disable RTL2832U remote controller");
@@ -662,37 +643,6 @@ static const struct rtl2832_platform_data rtl2832_r820t_platform_data = {
        .tuner = TUNER_RTL2832_R820T,
 };
 
-/* TODO: these are redundant information for rtl2832_sdr driver */
-static const struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .tuner = TUNER_RTL2832_FC0012
-};
-
-static const struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .tuner = TUNER_RTL2832_FC0013
-};
-
-static const struct rtl2832_config rtl28xxu_rtl2832_tua9001_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .tuner = TUNER_RTL2832_TUA9001,
-};
-
-static const struct rtl2832_config rtl28xxu_rtl2832_e4000_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .tuner = TUNER_RTL2832_E4000,
-};
-
-static const struct rtl2832_config rtl28xxu_rtl2832_r820t_config = {
-       .i2c_addr = 0x10,
-       .xtal = 28800000,
-       .tuner = TUNER_RTL2832_R820T,
-};
-
 static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d,
                int cmd, int arg)
 {
@@ -1062,10 +1012,10 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
        int ret;
        struct dvb_usb_device *d = adap_to_d(adap);
        struct rtl28xxu_priv *priv = d_to_priv(d);
-       struct rtl2832_platform_data *pdata = &priv->rtl2832_platform_data;
        struct dvb_frontend *fe = NULL;
        struct i2c_board_info info;
        struct i2c_client *client;
+       struct v4l2_subdev *subdev = NULL;
 
        dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
@@ -1080,10 +1030,6 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                 * that to the tuner driver */
                adap->fe[0]->ops.read_signal_strength =
                                adap->fe[0]->ops.tuner_ops.get_rf_strength;
-
-               /* attach SDR */
-               dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
-                               &rtl28xxu_rtl2832_fc0012_config, NULL);
                break;
        case TUNER_RTL2832_FC0013:
                fe = dvb_attach(fc0013_attach, adap->fe[0],
@@ -1092,16 +1038,8 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                /* fc0013 also supports signal strength reading */
                adap->fe[0]->ops.read_signal_strength =
                                adap->fe[0]->ops.tuner_ops.get_rf_strength;
-
-               /* attach SDR */
-               dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
-                               &rtl28xxu_rtl2832_fc0013_config, NULL);
                break;
        case TUNER_RTL2832_E4000: {
-                       struct v4l2_subdev *sd;
-                       struct i2c_adapter *i2c_adap_internal =
-                                       pdata->get_private_i2c_adapter(priv->i2c_client_demod);
-
                        struct e4000_config e4000_config = {
                                .fe = adap->fe[0],
                                .clock = 28800000,
@@ -1122,13 +1060,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                        }
 
                        priv->i2c_client_tuner = client;
-                       sd = i2c_get_clientdata(client);
-                       i2c_set_adapdata(i2c_adap_internal, d);
-
-                       /* attach SDR */
-                       dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0],
-                                       i2c_adap_internal,
-                                       &rtl28xxu_rtl2832_e4000_config, sd);
+                       subdev = i2c_get_clientdata(client);
                }
                break;
        case TUNER_RTL2832_FC2580:
@@ -1158,10 +1090,6 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                /* Use tuner to get the signal strength */
                adap->fe[0]->ops.read_signal_strength =
                                adap->fe[0]->ops.tuner_ops.get_rf_strength;
-
-               /* attach SDR */
-               dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
-                               &rtl28xxu_rtl2832_r820t_config, NULL);
                break;
        case TUNER_RTL2832_R828D:
                fe = dvb_attach(r820t_attach, adap->fe[0],
@@ -1177,21 +1105,53 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                        adap->fe[1]->ops.read_signal_strength =
                                        adap->fe[1]->ops.tuner_ops.get_rf_strength;
                }
-
-               /* attach SDR */
-               dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
-                               &rtl28xxu_rtl2832_r820t_config, NULL);
                break;
        default:
                dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
                                priv->tuner);
        }
-
        if (fe == NULL && priv->i2c_client_tuner == NULL) {
                ret = -ENODEV;
                goto err;
        }
 
+       /* register SDR */
+       switch (priv->tuner) {
+               struct platform_device *pdev;
+               struct rtl2832_sdr_platform_data pdata = {};
+
+       case TUNER_RTL2832_FC0012:
+       case TUNER_RTL2832_FC0013:
+       case TUNER_RTL2832_E4000:
+       case TUNER_RTL2832_R820T:
+       case TUNER_RTL2832_R828D:
+               pdata.clk = priv->rtl2832_platform_data.clk;
+               pdata.tuner = priv->tuner;
+               pdata.i2c_client = priv->i2c_client_demod;
+               pdata.bulk_read = priv->rtl2832_platform_data.bulk_read;
+               pdata.bulk_write = priv->rtl2832_platform_data.bulk_write;
+               pdata.update_bits = priv->rtl2832_platform_data.update_bits;
+               pdata.dvb_frontend = adap->fe[0];
+               pdata.dvb_usb_device = d;
+               pdata.v4l2_subdev = subdev;
+
+               request_module("%s", "rtl2832_sdr");
+               pdev = platform_device_register_data(&priv->i2c_client_demod->dev,
+                                                    "rtl2832_sdr",
+                                                    PLATFORM_DEVID_AUTO,
+                                                    &pdata, sizeof(pdata));
+               if (pdev == NULL || pdev->dev.driver == NULL)
+                       break;
+               if (!try_module_get(pdev->dev.driver->owner)) {
+                       platform_device_unregister(pdev);
+                       break;
+               }
+               priv->platform_device_sdr = pdev;
+               break;
+       default:
+               dev_dbg(&d->udev->dev, "no SDR for tuner=%d\n", priv->tuner);
+       }
+
        return 0;
 err:
        dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
@@ -1203,9 +1163,17 @@ static int rtl2832u_tuner_detach(struct dvb_usb_adapter *adap)
        struct dvb_usb_device *d = adap_to_d(adap);
        struct rtl28xxu_priv *priv = d_to_priv(d);
        struct i2c_client *client;
+       struct platform_device *pdev;
 
        dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
+       /* remove platform SDR */
+       pdev = priv->platform_device_sdr;
+       if (pdev) {
+               module_put(pdev->dev.driver->owner);
+               platform_device_unregister(pdev);
+       }
+
        /* remove I2C tuner */
        client = priv->i2c_client_tuner;
        if (client) {
index cb3fc6595332ad09b2fd346bdc5e71c815f879c9..62d32491fbe42cca40a72d4cf75f2632581f7ac9 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef RTL28XXU_H
 #define RTL28XXU_H
 
+#include <linux/platform_device.h>
+
 #include "dvb_usb.h"
 
 #include "rtl2830.h"
@@ -76,6 +78,7 @@ struct rtl28xxu_priv {
        struct i2c_client *i2c_client_demod;
        struct i2c_client *i2c_client_tuner;
        struct i2c_client *i2c_client_slave_demod;
+       struct platform_device *platform_device_sdr;
        #define SLAVE_DEMOD_NONE           0
        #define SLAVE_DEMOD_MN88472        1
        #define SLAVE_DEMOD_MN88473        2