^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Common methods for dibusb-based-receivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "dibusb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /* Max transfer size done by I2C transfer functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define MAX_XFER_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define deb_info(args...) dprintk(debug,0x01,args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* common stuff used by the different dibusb modules */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (adap->priv != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct dibusb_state *st = adap->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (st->ops.fifo_ctrl != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (st->ops.fifo_ctrl(adap->fe_adap[0].fe, onoff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) err("error while controlling the fifo of the demod.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) EXPORT_SYMBOL(dibusb_streaming_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (adap->priv != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct dibusb_state *st = adap->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (st->ops.pid_ctrl != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) st->ops.pid_ctrl(adap->fe_adap[0].fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) index, pid, onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) EXPORT_SYMBOL(dibusb_pid_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (adap->priv != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct dibusb_state *st = adap->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (st->ops.pid_parse != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (st->ops.pid_parse(adap->fe_adap[0].fe, onoff) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) err("could not handle pid_parser");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u8 *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) b = kmalloc(3, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) b[0] = DIBUSB_REQ_SET_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ret = dvb_usb_generic_write(d, b, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) kfree(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) EXPORT_SYMBOL(dibusb_power_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u8 *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) b = kmalloc(3, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (onoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) b[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ret = dvb_usb_generic_write(adap->dev, b, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) b[0] = DIBUSB_REQ_SET_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ret = dvb_usb_generic_write(adap->dev, b, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) kfree(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u8 *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) b = kmalloc(3, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) b[0] = DIBUSB_REQ_SET_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) b[2] = DIBUSB_IOCTL_POWER_WAKEUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = dvb_usb_generic_write(d, b, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) kfree(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) EXPORT_SYMBOL(dibusb2_0_power_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u8 *sndbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int ret, wo, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* write only ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) wo = (rbuf == NULL || rlen == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) len = 2 + wlen + (wo ? 0 : 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) sndbuf = kmalloc(MAX_XFER_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (!sndbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (4 + wlen > MAX_XFER_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) warn("i2c wr: len=%d is too big!\n", wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) memcpy(&sndbuf[2], wbuf, wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!wo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) sndbuf[wlen + 2] = (rlen >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) sndbuf[wlen + 3] = rlen & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ret = dvb_usb_generic_rw(d, sndbuf, len, rbuf, rlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) kfree(sndbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * I2C master xfer function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct dvb_usb_device *d = i2c_get_adapdata(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* write/read request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) && (msg[i+1].flags & I2C_M_RD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) msg[i+1].buf,msg[i+1].len) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) } else if ((msg[i].flags & I2C_M_RD) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) } else if (msg[i].addr != 0x50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* 0x50 is the address of the eeprom - we need to protect it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * from dibusb's bad i2c implementation: reads without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * writing the offset before are forbidden */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mutex_unlock(&d->i2c_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return I2C_FUNC_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct i2c_algorithm dibusb_i2c_algo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .master_xfer = dibusb_i2c_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .functionality = dibusb_i2c_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) EXPORT_SYMBOL(dibusb_i2c_algo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) buf = kzalloc(2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) buf[0] = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) rc = dibusb_i2c_msg(d, 0x50, &buf[0], 1, &buf[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *val = buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) EXPORT_SYMBOL(dibusb_read_eeprom_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * common remote control stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct rc_map_table rc_map_dibusb_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) { 0x0016, KEY_POWER },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) { 0x0010, KEY_MUTE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) { 0x0003, KEY_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) { 0x0001, KEY_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { 0x0006, KEY_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { 0x0009, KEY_4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { 0x001d, KEY_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { 0x001f, KEY_6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { 0x000d, KEY_7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { 0x0019, KEY_8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { 0x001b, KEY_9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { 0x0015, KEY_0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) { 0x0005, KEY_CHANNELUP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { 0x0002, KEY_CHANNELDOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { 0x001e, KEY_VOLUMEUP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) { 0x000a, KEY_VOLUMEDOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) { 0x0011, KEY_RECORD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) { 0x0014, KEY_PLAY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) { 0x001a, KEY_STOP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) { 0x0040, KEY_REWIND },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) { 0x0012, KEY_FASTFORWARD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) { 0x004c, KEY_PAUSE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) { 0x004d, KEY_SCREEN }, /* Full screen mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) { 0x000c, KEY_CANCEL }, /* Cancel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) { 0x001c, KEY_EPG }, /* EPG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) { 0x0000, KEY_TAB }, /* Tab */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) { 0x0048, KEY_INFO }, /* Preview */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) { 0x0004, KEY_LIST }, /* RecordList */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) { 0x000f, KEY_TEXT }, /* Teletext */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* Key codes for the KWorld/ADSTech/JetWay remote. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { 0x8612, KEY_POWER },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { 0x860f, KEY_SELECT }, /* source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { 0x860c, KEY_UNKNOWN }, /* scan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { 0x860b, KEY_EPG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) { 0x8610, KEY_MUTE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) { 0x8601, KEY_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { 0x8602, KEY_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) { 0x8603, KEY_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) { 0x8604, KEY_4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) { 0x8605, KEY_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) { 0x8606, KEY_6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) { 0x8607, KEY_7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) { 0x8608, KEY_8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) { 0x8609, KEY_9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) { 0x860a, KEY_0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) { 0x8618, KEY_ZOOM },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) { 0x861c, KEY_UNKNOWN }, /* preview */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { 0x8613, KEY_UNKNOWN }, /* snap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { 0x8600, KEY_UNDO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { 0x861d, KEY_RECORD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { 0x860d, KEY_STOP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) { 0x860e, KEY_PAUSE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) { 0x8616, KEY_PLAY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) { 0x8611, KEY_BACK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) { 0x8619, KEY_FORWARD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) { 0x8614, KEY_UNKNOWN }, /* pip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) { 0x8615, KEY_ESC },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) { 0x861a, KEY_UP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) { 0x861e, KEY_DOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) { 0x861f, KEY_LEFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) { 0x861b, KEY_RIGHT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Key codes for the DiBcom MOD3000 remote. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { 0x8000, KEY_MUTE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) { 0x8001, KEY_TEXT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) { 0x8002, KEY_HOME },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) { 0x8003, KEY_POWER },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) { 0x8004, KEY_RED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) { 0x8005, KEY_GREEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { 0x8006, KEY_YELLOW },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) { 0x8007, KEY_BLUE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) { 0x8008, KEY_DVD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) { 0x8009, KEY_AUDIO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) { 0x800a, KEY_IMAGES }, /* Pictures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) { 0x800b, KEY_VIDEO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) { 0x800c, KEY_BACK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) { 0x800d, KEY_UP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) { 0x800e, KEY_RADIO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) { 0x800f, KEY_EPG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) { 0x8010, KEY_LEFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) { 0x8011, KEY_OK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) { 0x8012, KEY_RIGHT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) { 0x8013, KEY_UNKNOWN }, /* SAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) { 0x8014, KEY_TV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) { 0x8015, KEY_DOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) { 0x8016, KEY_MENU }, /* DVD Menu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) { 0x8017, KEY_LAST },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) { 0x8018, KEY_RECORD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) { 0x8019, KEY_STOP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) { 0x801a, KEY_PAUSE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) { 0x801b, KEY_PLAY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) { 0x801c, KEY_PREVIOUS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) { 0x801d, KEY_REWIND },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) { 0x801e, KEY_FASTFORWARD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) { 0x801f, KEY_NEXT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) { 0x8040, KEY_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) { 0x8041, KEY_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) { 0x8042, KEY_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) { 0x8043, KEY_CHANNELUP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) { 0x8044, KEY_4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) { 0x8045, KEY_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) { 0x8046, KEY_6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) { 0x8047, KEY_CHANNELDOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) { 0x8048, KEY_7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) { 0x8049, KEY_8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) { 0x804a, KEY_9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) { 0x804b, KEY_VOLUMEUP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) { 0x804c, KEY_CLEAR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) { 0x804d, KEY_0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) { 0x804e, KEY_ENTER },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) { 0x804f, KEY_VOLUMEDOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) EXPORT_SYMBOL(rc_map_dibusb_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) buf = kmalloc(5, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) buf[0] = DIBUSB_REQ_POLL_REMOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret = dvb_usb_generic_rw(d, buf, 1, buf, 5, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dvb_usb_nec_rc_key_to_event(d, buf, event, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (buf[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) deb_info("key: %*ph\n", 5, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) EXPORT_SYMBOL(dibusb_rc_query);