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
14DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
15
16struct 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
25static 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(usb_dev: d->udev, usb_sndbulkpipe(d->udev, 0x04), data: dev->buf,
39 len: wlen, actual_length: &actual_length, timeout: 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(usb_dev: d->udev, usb_rcvbulkpipe(d->udev, 0x83),
47 data: dev->buf, len: rlen, actual_length: &actual_length, timeout: 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(usb_dev: d->udev,
64 usb_rcvbulkpipe(d->udev, 0x83),
65 data: dev->buf, len: rlen, actual_length: &actual_length,
66 timeout: 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
80err_mutex_unlock:
81 mutex_unlock(lock: &d->usb_mutex);
82 return ret;
83}
84
85static 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, wbuf: buf, wlen: 7, NULL, rlen: 0);
94 if (ret)
95 goto err;
96
97 return 0;
98err:
99 dev_dbg(&intf->dev, "failed=%d\n", ret);
100 return ret;
101}
102
103static 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, wbuf: buf, wlen: 7, rbuf: buf, rlen: 7);
112 if (ret)
113 goto err;
114
115 *val = buf[6];
116
117 return 0;
118err:
119 dev_dbg(&intf->dev, "failed=%d\n", ret);
120 return ret;
121}
122
123static 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(parent: &intf->dev,
143 name: "zd1301_demod",
144 PLATFORM_DEVID_AUTO,
145 data: &dev->demod_pdata,
146 size: sizeof(dev->demod_pdata));
147 if (IS_ERR(ptr: pdev)) {
148 ret = PTR_ERR(ptr: pdev);
149 goto err;
150 }
151 if (!pdev->dev.driver) {
152 ret = -ENODEV;
153 goto err_platform_device_unregister;
154 }
155 if (!try_module_get(module: 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_client_device(adap: adapter, info: &board_info);
176 if (!i2c_client_has_driver(client)) {
177 ret = -ENODEV;
178 goto err_module_put_demod;
179 }
180 if (!try_module_get(module: 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;
190err_i2c_unregister_device:
191 i2c_unregister_device(client);
192err_module_put_demod:
193 module_put(module: pdev->dev.driver->owner);
194err_platform_device_unregister:
195 platform_device_unregister(pdev);
196err:
197 dev_dbg(&intf->dev, "failed=%d\n", ret);
198 return ret;
199}
200
201static 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(module: client->dev.driver->owner);
217 i2c_unregister_device(client);
218 }
219
220 /* Remove platform demod */
221 if (pdev) {
222 module_put(module: pdev->dev.driver->owner);
223 platform_device_unregister(pdev);
224 }
225
226 return 0;
227}
228
229static 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, wbuf: buf, wlen: 3, NULL, rlen: 0);
239 if (ret)
240 goto err;
241
242 return 0;
243err:
244 dev_dbg(&intf->dev, "failed=%d\n", ret);
245 return ret;
246}
247
248static 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
266static 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};
271MODULE_DEVICE_TABLE(usb, zd1301_id_table);
272
273/* Usb specific object needed to register this driver with the usb subsystem */
274static 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};
285module_usb_driver(zd1301_usb_driver);
286
287MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
288MODULE_DESCRIPTION("ZyDAS ZD1301 driver");
289MODULE_LICENSE("GPL");
290

source code of linux/drivers/media/usb/dvb-usb-v2/zd1301.c