int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold) { int ret; u8 *mac; mac = kmalloc(6, GFP_ATOMIC); if (!mac) return -ENOMEM; /* Try to read the mac address */ ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); if (ret == 6) *cold = 0; else *cold = 1; kfree(mac); if (*cold) { __az6007_write(udev, 0x09, 1, 0, NULL, 0); __az6007_write(udev, 0x00, 0, 0, NULL, 0); __az6007_write(udev, 0x00, 0, 0, NULL, 0); } deb_info("Device is on %s state\n", *cold ? "warm" : "cold"); return 0; }
static int az6007_identify_state(struct dvb_usb_device *d, const char **name) { int ret; u8 *mac; pr_debug("Identifying az6007 state\n"); mac = kmalloc(6, GFP_ATOMIC); if (!mac) return -ENOMEM; /* Try to read the mac address */ ret = __az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6); if (ret == 6) ret = WARM; else ret = COLD; kfree(mac); if (ret == COLD) { __az6007_write(d->udev, 0x09, 1, 0, NULL, 0); __az6007_write(d->udev, 0x00, 0, 0, NULL, 0); __az6007_write(d->udev, 0x00, 0, 0, NULL, 0); } pr_debug("Device is on %s state\n", ret == WARM ? "warm" : "cold"); return ret; }
static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) { struct az6007_device_state *st = d->priv; int ret; if (mutex_lock_interruptible(&st->mutex) < 0) return -EAGAIN; ret = __az6007_write(d->udev, req, value, index, b, blen); mutex_unlock(&st->mutex); return ret; }
/* I2C */ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct az6007_device_state *st = d->priv; int i, j, len; int ret = 0; u16 index; u16 value; int length; u8 req, addr; if (mutex_lock_interruptible(&st->mutex) < 0) return -EAGAIN; for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; if (((i + 1) < num) && (msgs[i].len == 1) && (!msgs[i].flags & I2C_M_RD) && (msgs[i + 1].flags & I2C_M_RD) && (msgs[i].addr == msgs[i + 1].addr)) { /* * A write + read xfer for the same address, where * the first xfer has just 1 byte length. * Need to join both into one operation */ if (dvb_usb_az6007_debug & 2) printk(KERN_DEBUG "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", addr, msgs[i].len, msgs[i + 1].len); req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; ret = __az6007_read(d->udev, req, value, index, st->data, length); if (ret >= len) { for (j = 0; j < len; j++) { msgs[i + 1].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", msgs[i + 1].buf[j]); } } else ret = -EIO; i++; } else if (!(msgs[i].flags & I2C_M_RD)) { /* write bytes */ if (dvb_usb_az6007_debug & 2) printk(KERN_DEBUG "az6007 I2C xfer write addr=0x%x len=%d: ", addr, msgs[i].len); req = AZ6007_I2C_WR; index = msgs[i].buf[0]; value = addr | (1 << 8); length = msgs[i].len - 1; len = msgs[i].len - 1; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]); for (j = 0; j < len; j++) { st->data[j] = msgs[i].buf[j + 1]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", st->data[j]); } ret = __az6007_write(d->udev, req, value, index, st->data, length); } else { /* read bytes */ if (dvb_usb_az6007_debug & 2) printk(KERN_DEBUG "az6007 I2C xfer read addr=0x%x len=%d: ", addr, msgs[i].len); req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr; length = msgs[i].len + 6; len = msgs[i].len; ret = __az6007_read(d->udev, req, value, index, st->data, length); for (j = 0; j < len; j++) { msgs[i].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", st->data[j + 5]); } } if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "\n"); if (ret < 0) goto err; } err: mutex_unlock(&st->mutex); if (ret < 0) { info("%s ERROR: %i", __func__, ret); return ret; } return num; }