root/drivers/media/usb/dvb-usb-v2/zd1301.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zd1301_ctrl_msg
  2. zd1301_demod_wreg
  3. zd1301_demod_rreg
  4. zd1301_frontend_attach
  5. zd1301_frontend_detach
  6. zd1301_streaming_ctrl

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * ZyDAS ZD1301 driver (USB interface)
   4  *
   5  * Copyright (C) 2015 Antti Palosaari <crope@iki.fi>
   6  */
   7 
   8 #include "dvb_usb.h"
   9 #include "zd1301_demod.h"
  10 #include "mt2060.h"
  11 #include <linux/i2c.h>
  12 #include <linux/platform_device.h>
  13 
  14 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  15 
  16 struct zd1301_dev {
  17         #define BUF_LEN 8
  18         u8 buf[BUF_LEN]; /* bulk USB control message */
  19         struct zd1301_demod_platform_data demod_pdata;
  20         struct mt2060_platform_data mt2060_pdata;
  21         struct platform_device *platform_device_demod;
  22         struct i2c_client *i2c_client_tuner;
  23 };
  24 
  25 static int zd1301_ctrl_msg(struct dvb_usb_device *d, const u8 *wbuf,
  26                            unsigned int wlen, u8 *rbuf, unsigned int rlen)
  27 {
  28         struct zd1301_dev *dev = d_to_priv(d);
  29         struct usb_interface *intf = d->intf;
  30         int ret, actual_length;
  31 
  32         mutex_lock(&d->usb_mutex);
  33 
  34         memcpy(&dev->buf, wbuf, wlen);
  35 
  36         dev_dbg(&intf->dev, ">>> %*ph\n", wlen, dev->buf);
  37 
  38         ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, 0x04), dev->buf,
  39                            wlen, &actual_length, 1000);
  40         if (ret) {
  41                 dev_err(&intf->dev, "1st usb_bulk_msg() failed %d\n", ret);
  42                 goto err_mutex_unlock;
  43         }
  44 
  45         if (rlen) {
  46                 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 0x83),
  47                                    dev->buf, rlen, &actual_length, 1000);
  48                 if (ret) {
  49                         dev_err(&intf->dev,
  50                                 "2nd usb_bulk_msg() failed %d\n", ret);
  51                         goto err_mutex_unlock;
  52                 }
  53 
  54                 dev_dbg(&intf->dev, "<<< %*ph\n", actual_length, dev->buf);
  55 
  56                 if (actual_length != rlen) {
  57                         /*
  58                          * Chip replies often with 3 byte len stub. On that case
  59                          * we have to query new reply.
  60                          */
  61                         dev_dbg(&intf->dev, "repeating reply message\n");
  62 
  63                         ret = usb_bulk_msg(d->udev,
  64                                            usb_rcvbulkpipe(d->udev, 0x83),
  65                                            dev->buf, rlen, &actual_length,
  66                                            1000);
  67                         if (ret) {
  68                                 dev_err(&intf->dev,
  69                                         "3rd usb_bulk_msg() failed %d\n", ret);
  70                                 goto err_mutex_unlock;
  71                         }
  72 
  73                         dev_dbg(&intf->dev,
  74                                 "<<< %*ph\n", actual_length, dev->buf);
  75                 }
  76 
  77                 memcpy(rbuf, dev->buf, rlen);
  78         }
  79 
  80 err_mutex_unlock:
  81         mutex_unlock(&d->usb_mutex);
  82         return ret;
  83 }
  84 
  85 static int zd1301_demod_wreg(void *reg_priv, u16 reg, u8 val)
  86 {
  87         struct dvb_usb_device *d = reg_priv;
  88         struct usb_interface *intf = d->intf;
  89         int ret;
  90         u8 buf[7] = {0x07, 0x00, 0x03, 0x01,
  91                      (reg >> 0) & 0xff, (reg >> 8) & 0xff, val};
  92 
  93         ret = zd1301_ctrl_msg(d, buf, 7, NULL, 0);
  94         if (ret)
  95                 goto err;
  96 
  97         return 0;
  98 err:
  99         dev_dbg(&intf->dev, "failed=%d\n", ret);
 100         return ret;
 101 }
 102 
 103 static int zd1301_demod_rreg(void *reg_priv, u16 reg, u8 *val)
 104 {
 105         struct dvb_usb_device *d = reg_priv;
 106         struct usb_interface *intf = d->intf;
 107         int ret;
 108         u8 buf[7] = {0x07, 0x00, 0x04, 0x01,
 109                      (reg >> 0) & 0xff, (reg >> 8) & 0xff, 0};
 110 
 111         ret = zd1301_ctrl_msg(d, buf, 7, buf, 7);
 112         if (ret)
 113                 goto err;
 114 
 115         *val = buf[6];
 116 
 117         return 0;
 118 err:
 119         dev_dbg(&intf->dev, "failed=%d\n", ret);
 120         return ret;
 121 }
 122 
 123 static int zd1301_frontend_attach(struct dvb_usb_adapter *adap)
 124 {
 125         struct dvb_usb_device *d = adap_to_d(adap);
 126         struct zd1301_dev *dev = adap_to_priv(adap);
 127         struct usb_interface *intf = d->intf;
 128         struct platform_device *pdev;
 129         struct i2c_client *client;
 130         struct i2c_board_info board_info;
 131         struct i2c_adapter *adapter;
 132         struct dvb_frontend *frontend;
 133         int ret;
 134 
 135         dev_dbg(&intf->dev, "\n");
 136 
 137         /* Add platform demod */
 138         dev->demod_pdata.reg_priv = d;
 139         dev->demod_pdata.reg_read = zd1301_demod_rreg;
 140         dev->demod_pdata.reg_write = zd1301_demod_wreg;
 141         request_module("%s", "zd1301_demod");
 142         pdev = platform_device_register_data(&intf->dev,
 143                                              "zd1301_demod",
 144                                              PLATFORM_DEVID_AUTO,
 145                                              &dev->demod_pdata,
 146                                              sizeof(dev->demod_pdata));
 147         if (IS_ERR(pdev)) {
 148                 ret = PTR_ERR(pdev);
 149                 goto err;
 150         }
 151         if (!pdev->dev.driver) {
 152                 ret = -ENODEV;
 153                 goto err;
 154         }
 155         if (!try_module_get(pdev->dev.driver->owner)) {
 156                 ret = -ENODEV;
 157                 goto err_platform_device_unregister;
 158         }
 159 
 160         adapter = zd1301_demod_get_i2c_adapter(pdev);
 161         frontend = zd1301_demod_get_dvb_frontend(pdev);
 162         if (!adapter || !frontend) {
 163                 ret = -ENODEV;
 164                 goto err_module_put_demod;
 165         }
 166 
 167         /* Add I2C tuner */
 168         dev->mt2060_pdata.i2c_write_max = 9;
 169         dev->mt2060_pdata.dvb_frontend = frontend;
 170         memset(&board_info, 0, sizeof(board_info));
 171         strscpy(board_info.type, "mt2060", I2C_NAME_SIZE);
 172         board_info.addr = 0x60;
 173         board_info.platform_data = &dev->mt2060_pdata;
 174         request_module("%s", "mt2060");
 175         client = i2c_new_device(adapter, &board_info);
 176         if (!client || !client->dev.driver) {
 177                 ret = -ENODEV;
 178                 goto err_module_put_demod;
 179         }
 180         if (!try_module_get(client->dev.driver->owner)) {
 181                 ret = -ENODEV;
 182                 goto err_i2c_unregister_device;
 183         }
 184 
 185         dev->platform_device_demod = pdev;
 186         dev->i2c_client_tuner = client;
 187         adap->fe[0] = frontend;
 188 
 189         return 0;
 190 err_i2c_unregister_device:
 191         i2c_unregister_device(client);
 192 err_module_put_demod:
 193         module_put(pdev->dev.driver->owner);
 194 err_platform_device_unregister:
 195         platform_device_unregister(pdev);
 196 err:
 197         dev_dbg(&intf->dev, "failed=%d\n", ret);
 198         return ret;
 199 }
 200 
 201 static int zd1301_frontend_detach(struct dvb_usb_adapter *adap)
 202 {
 203         struct dvb_usb_device *d = adap_to_d(adap);
 204         struct zd1301_dev *dev = d_to_priv(d);
 205         struct usb_interface *intf = d->intf;
 206         struct platform_device *pdev;
 207         struct i2c_client *client;
 208 
 209         dev_dbg(&intf->dev, "\n");
 210 
 211         client = dev->i2c_client_tuner;
 212         pdev = dev->platform_device_demod;
 213 
 214         /* Remove I2C tuner */
 215         if (client) {
 216                 module_put(client->dev.driver->owner);
 217                 i2c_unregister_device(client);
 218         }
 219 
 220         /* Remove platform demod */
 221         if (pdev) {
 222                 module_put(pdev->dev.driver->owner);
 223                 platform_device_unregister(pdev);
 224         }
 225 
 226         return 0;
 227 }
 228 
 229 static int zd1301_streaming_ctrl(struct dvb_frontend *fe, int onoff)
 230 {
 231         struct dvb_usb_device *d = fe_to_d(fe);
 232         struct usb_interface *intf = d->intf;
 233         int ret;
 234         u8 buf[3] = {0x03, 0x00, onoff ? 0x07 : 0x08};
 235 
 236         dev_dbg(&intf->dev, "onoff=%d\n", onoff);
 237 
 238         ret = zd1301_ctrl_msg(d, buf, 3, NULL, 0);
 239         if (ret)
 240                 goto err;
 241 
 242         return 0;
 243 err:
 244         dev_dbg(&intf->dev, "failed=%d\n", ret);
 245         return ret;
 246 }
 247 
 248 static const struct dvb_usb_device_properties zd1301_props = {
 249         .driver_name = KBUILD_MODNAME,
 250         .owner = THIS_MODULE,
 251         .adapter_nr = adapter_nr,
 252         .size_of_priv = sizeof(struct zd1301_dev),
 253 
 254         .frontend_attach = zd1301_frontend_attach,
 255         .frontend_detach = zd1301_frontend_detach,
 256         .streaming_ctrl  = zd1301_streaming_ctrl,
 257 
 258         .num_adapters = 1,
 259         .adapter = {
 260                 {
 261                         .stream = DVB_USB_STREAM_BULK(0x81, 6, 21 * 188),
 262                 },
 263         },
 264 };
 265 
 266 static const struct usb_device_id zd1301_id_table[] = {
 267         {DVB_USB_DEVICE(USB_VID_ZYDAS, 0x13a1, &zd1301_props,
 268                         "ZyDAS ZD1301 reference design", NULL)},
 269         {}
 270 };
 271 MODULE_DEVICE_TABLE(usb, zd1301_id_table);
 272 
 273 /* Usb specific object needed to register this driver with the usb subsystem */
 274 static struct usb_driver zd1301_usb_driver = {
 275         .name = KBUILD_MODNAME,
 276         .id_table = zd1301_id_table,
 277         .probe = dvb_usbv2_probe,
 278         .disconnect = dvb_usbv2_disconnect,
 279         .suspend = dvb_usbv2_suspend,
 280         .resume = dvb_usbv2_resume,
 281         .reset_resume = dvb_usbv2_reset_resume,
 282         .no_dynamic_id = 1,
 283         .soft_unbind = 1,
 284 };
 285 module_usb_driver(zd1301_usb_driver);
 286 
 287 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 288 MODULE_DESCRIPTION("ZyDAS ZD1301 driver");
 289 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */