Path: blob/master/drivers/media/video/em28xx/em28xx-i2c.c
17887 views
/*1em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices23Copyright (C) 2005 Ludovico Cavedon <[email protected]>4Markus Rechberger <[email protected]>5Mauro Carvalho Chehab <[email protected]>6Sascha Sommer <[email protected]>78This program is free software; you can redistribute it and/or modify9it under the terms of the GNU General Public License as published by10the Free Software Foundation; either version 2 of the License, or11(at your option) any later version.1213This program is distributed in the hope that it will be useful,14but WITHOUT ANY WARRANTY; without even the implied warranty of15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16GNU General Public License for more details.1718You should have received a copy of the GNU General Public License19along with this program; if not, write to the Free Software20Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.21*/2223#include <linux/module.h>24#include <linux/kernel.h>25#include <linux/usb.h>26#include <linux/i2c.h>2728#include "em28xx.h"29#include "tuner-xc2028.h"30#include <media/v4l2-common.h>31#include <media/tuner.h>3233/* ----------------------------------------------------------- */3435static unsigned int i2c_scan;36module_param(i2c_scan, int, 0444);37MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");3839static unsigned int i2c_debug;40module_param(i2c_debug, int, 0644);41MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");424344#define dprintk1(lvl, fmt, args...) \45do { \46if (i2c_debug >= lvl) { \47printk(fmt, ##args); \48} \49} while (0)5051#define dprintk2(lvl, fmt, args...) \52do { \53if (i2c_debug >= lvl) { \54printk(KERN_DEBUG "%s at %s: " fmt, \55dev->name, __func__ , ##args); \56} \57} while (0)5859/*60* em2800_i2c_send_max4()61* send up to 4 bytes to the i2c device62*/63static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,64char *buf, int len)65{66int ret;67int write_timeout;68unsigned char b2[6];69BUG_ON(len < 1 || len > 4);70b2[5] = 0x80 + len - 1;71b2[4] = addr;72b2[3] = buf[0];73if (len > 1)74b2[2] = buf[1];75if (len > 2)76b2[1] = buf[2];77if (len > 3)78b2[0] = buf[3];7980ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);81if (ret != 2 + len) {82em28xx_warn("writing to i2c device failed (error=%i)\n", ret);83return -EIO;84}85for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;86write_timeout -= 5) {87ret = dev->em28xx_read_reg(dev, 0x05);88if (ret == 0x80 + len - 1)89return len;90msleep(5);91}92em28xx_warn("i2c write timed out\n");93return -EIO;94}9596/*97* em2800_i2c_send_bytes()98*/99static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf,100short len)101{102char *bufPtr = buf;103int ret;104int wrcount = 0;105int count;106int maxLen = 4;107struct em28xx *dev = (struct em28xx *)data;108while (len > 0) {109count = (len > maxLen) ? maxLen : len;110ret = em2800_i2c_send_max4(dev, addr, bufPtr, count);111if (ret > 0) {112len -= count;113bufPtr += count;114wrcount += count;115} else116return (ret < 0) ? ret : -EFAULT;117}118return wrcount;119}120121/*122* em2800_i2c_check_for_device()123* check if there is a i2c_device at the supplied address124*/125static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)126{127char msg;128int ret;129int write_timeout;130msg = addr;131ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1);132if (ret < 0) {133em28xx_warn("setting i2c device address failed (error=%i)\n",134ret);135return ret;136}137msg = 0x84;138ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1);139if (ret < 0) {140em28xx_warn("preparing i2c read failed (error=%i)\n", ret);141return ret;142}143for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;144write_timeout -= 5) {145unsigned reg = dev->em28xx_read_reg(dev, 0x5);146147if (reg == 0x94)148return -ENODEV;149else if (reg == 0x84)150return 0;151msleep(5);152}153return -ENODEV;154}155156/*157* em2800_i2c_recv_bytes()158* read from the i2c device159*/160static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,161char *buf, int len)162{163int ret;164/* check for the device and set i2c read address */165ret = em2800_i2c_check_for_device(dev, addr);166if (ret) {167em28xx_warn168("preparing read at i2c address 0x%x failed (error=%i)\n",169addr, ret);170return ret;171}172ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len);173if (ret < 0) {174em28xx_warn("reading from i2c device at 0x%x failed (error=%i)",175addr, ret);176return ret;177}178return ret;179}180181/*182* em28xx_i2c_send_bytes()183* untested for more than 4 bytes184*/185static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf,186short len, int stop)187{188int wrcount = 0;189struct em28xx *dev = (struct em28xx *)data;190191wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);192193return wrcount;194}195196/*197* em28xx_i2c_recv_bytes()198* read a byte from the i2c device199*/200static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,201char *buf, int len)202{203int ret;204ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);205if (ret < 0) {206em28xx_warn("reading i2c device failed (error=%i)\n", ret);207return ret;208}209if (dev->em28xx_read_reg(dev, 0x5) != 0)210return -ENODEV;211return ret;212}213214/*215* em28xx_i2c_check_for_device()216* check if there is a i2c_device at the supplied address217*/218static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr)219{220char msg;221int ret;222msg = addr;223224ret = dev->em28xx_read_reg_req(dev, 2, addr);225if (ret < 0) {226em28xx_warn("reading from i2c device failed (error=%i)\n", ret);227return ret;228}229if (dev->em28xx_read_reg(dev, 0x5) != 0)230return -ENODEV;231return 0;232}233234/*235* em28xx_i2c_xfer()236* the main i2c transfer function237*/238static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,239struct i2c_msg msgs[], int num)240{241struct em28xx *dev = i2c_adap->algo_data;242int addr, rc, i, byte;243244if (num <= 0)245return 0;246for (i = 0; i < num; i++) {247addr = msgs[i].addr << 1;248dprintk2(2, "%s %s addr=%x len=%d:",249(msgs[i].flags & I2C_M_RD) ? "read" : "write",250i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);251if (!msgs[i].len) { /* no len: check only for device presence */252if (dev->board.is_em2800)253rc = em2800_i2c_check_for_device(dev, addr);254else255rc = em28xx_i2c_check_for_device(dev, addr);256if (rc < 0) {257dprintk2(2, " no device\n");258return rc;259}260261} else if (msgs[i].flags & I2C_M_RD) {262/* read bytes */263if (dev->board.is_em2800)264rc = em2800_i2c_recv_bytes(dev, addr,265msgs[i].buf,266msgs[i].len);267else268rc = em28xx_i2c_recv_bytes(dev, addr,269msgs[i].buf,270msgs[i].len);271if (i2c_debug >= 2) {272for (byte = 0; byte < msgs[i].len; byte++)273printk(" %02x", msgs[i].buf[byte]);274}275} else {276/* write bytes */277if (i2c_debug >= 2) {278for (byte = 0; byte < msgs[i].len; byte++)279printk(" %02x", msgs[i].buf[byte]);280}281if (dev->board.is_em2800)282rc = em2800_i2c_send_bytes(dev, addr,283msgs[i].buf,284msgs[i].len);285else286rc = em28xx_i2c_send_bytes(dev, addr,287msgs[i].buf,288msgs[i].len,289i == num - 1);290}291if (rc < 0)292goto err;293if (i2c_debug >= 2)294printk("\n");295}296297return num;298err:299dprintk2(2, " ERROR: %i\n", rc);300return rc;301}302303/* based on linux/sunrpc/svcauth.h and linux/hash.h304* The original hash function returns a different value, if arch is x86_64305* or i386.306*/307static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits)308{309unsigned long hash = 0;310unsigned long l = 0;311int len = 0;312unsigned char c;313do {314if (len == length) {315c = (char)len;316len = -1;317} else318c = *buf++;319l = (l << 8) | c;320len++;321if ((len & (32 / 8 - 1)) == 0)322hash = ((hash^l) * 0x9e370001UL);323} while (len);324325return (hash >> (32 - bits)) & 0xffffffffUL;326}327328static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)329{330unsigned char buf, *p = eedata;331struct em28xx_eeprom *em_eeprom = (void *)eedata;332int i, err, size = len, block;333334if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {335/* Empia switched to a 16-bit addressable eeprom in newer336devices. While we could certainly write a routine to read337the eeprom, there is nothing of use in there that cannot be338accessed through registers, and there is the risk that we339could corrupt the eeprom (since a 16-bit read call is340interpreted as a write call by 8-bit eeproms).341*/342return 0;343}344345dev->i2c_client.addr = 0xa0 >> 1;346347/* Check if board has eeprom */348err = i2c_master_recv(&dev->i2c_client, &buf, 0);349if (err < 0) {350em28xx_errdev("board has no eeprom\n");351memset(eedata, 0, len);352return -ENODEV;353}354355buf = 0;356357err = i2c_master_send(&dev->i2c_client, &buf, 1);358if (err != 1) {359printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",360dev->name, err);361return err;362}363while (size > 0) {364if (size > 16)365block = 16;366else367block = size;368369if (block !=370(err = i2c_master_recv(&dev->i2c_client, p, block))) {371printk(KERN_WARNING372"%s: i2c eeprom read error (err=%d)\n",373dev->name, err);374return err;375}376size -= block;377p += block;378}379for (i = 0; i < len; i++) {380if (0 == (i % 16))381printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);382printk(" %02x", eedata[i]);383if (15 == (i % 16))384printk("\n");385}386387if (em_eeprom->id == 0x9567eb1a)388dev->hash = em28xx_hash_mem(eedata, len, 32);389390printk(KERN_INFO "%s: EEPROM ID= 0x%08x, EEPROM hash = 0x%08lx\n",391dev->name, em_eeprom->id, dev->hash);392393printk(KERN_INFO "%s: EEPROM info:\n", dev->name);394395switch (em_eeprom->chip_conf >> 4 & 0x3) {396case 0:397printk(KERN_INFO "%s:\tNo audio on board.\n", dev->name);398break;399case 1:400printk(KERN_INFO "%s:\tAC97 audio (5 sample rates)\n",401dev->name);402break;403case 2:404printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n",405dev->name);406break;407case 3:408printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n",409dev->name);410break;411}412413if (em_eeprom->chip_conf & 1 << 3)414printk(KERN_INFO "%s:\tUSB Remote wakeup capable\n", dev->name);415416if (em_eeprom->chip_conf & 1 << 2)417printk(KERN_INFO "%s:\tUSB Self power capable\n", dev->name);418419switch (em_eeprom->chip_conf & 0x3) {420case 0:421printk(KERN_INFO "%s:\t500mA max power\n", dev->name);422break;423case 1:424printk(KERN_INFO "%s:\t400mA max power\n", dev->name);425break;426case 2:427printk(KERN_INFO "%s:\t300mA max power\n", dev->name);428break;429case 3:430printk(KERN_INFO "%s:\t200mA max power\n", dev->name);431break;432}433printk(KERN_INFO "%s:\tTable at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",434dev->name,435em_eeprom->string_idx_table,436em_eeprom->string1,437em_eeprom->string2,438em_eeprom->string3);439440return 0;441}442443/* ----------------------------------------------------------- */444445/*446* functionality()447*/448static u32 functionality(struct i2c_adapter *adap)449{450return I2C_FUNC_SMBUS_EMUL;451}452453static struct i2c_algorithm em28xx_algo = {454.master_xfer = em28xx_i2c_xfer,455.functionality = functionality,456};457458static struct i2c_adapter em28xx_adap_template = {459.owner = THIS_MODULE,460.name = "em28xx",461.algo = &em28xx_algo,462};463464static struct i2c_client em28xx_client_template = {465.name = "em28xx internal",466};467468/* ----------------------------------------------------------- */469470/*471* i2c_devs472* incomplete list of known devices473*/474static char *i2c_devs[128] = {475[0x4a >> 1] = "saa7113h",476[0x60 >> 1] = "remote IR sensor",477[0x8e >> 1] = "remote IR sensor",478[0x86 >> 1] = "tda9887",479[0x80 >> 1] = "msp34xx",480[0x88 >> 1] = "msp34xx",481[0xa0 >> 1] = "eeprom",482[0xb0 >> 1] = "tda9874",483[0xb8 >> 1] = "tvp5150a",484[0xba >> 1] = "webcam sensor or tvp5150a",485[0xc0 >> 1] = "tuner (analog)",486[0xc2 >> 1] = "tuner (analog)",487[0xc4 >> 1] = "tuner (analog)",488[0xc6 >> 1] = "tuner (analog)",489};490491/*492* do_i2c_scan()493* check i2c address range for devices494*/495void em28xx_do_i2c_scan(struct em28xx *dev)496{497u8 i2c_devicelist[128];498unsigned char buf;499int i, rc;500501memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist));502503for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {504dev->i2c_client.addr = i;505rc = i2c_master_recv(&dev->i2c_client, &buf, 0);506if (rc < 0)507continue;508i2c_devicelist[i] = i;509printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n",510dev->name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");511}512513dev->i2c_hash = em28xx_hash_mem(i2c_devicelist,514ARRAY_SIZE(i2c_devicelist), 32);515}516517/*518* em28xx_i2c_register()519* register i2c bus520*/521int em28xx_i2c_register(struct em28xx *dev)522{523int retval;524525BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg);526BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req);527dev->i2c_adap = em28xx_adap_template;528dev->i2c_adap.dev.parent = &dev->udev->dev;529strcpy(dev->i2c_adap.name, dev->name);530dev->i2c_adap.algo_data = dev;531i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);532533retval = i2c_add_adapter(&dev->i2c_adap);534if (retval < 0) {535em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n",536__func__, retval);537return retval;538}539540dev->i2c_client = em28xx_client_template;541dev->i2c_client.adapter = &dev->i2c_adap;542543retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));544if ((retval < 0) && (retval != -ENODEV)) {545em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n",546__func__, retval);547548return retval;549}550551if (i2c_scan)552em28xx_do_i2c_scan(dev);553554/* Instantiate the IR receiver device, if present */555em28xx_register_i2c_ir(dev);556557return 0;558}559560/*561* em28xx_i2c_unregister()562* unregister i2c_bus563*/564int em28xx_i2c_unregister(struct em28xx *dev)565{566i2c_del_adapter(&dev->i2c_adap);567return 0;568}569570571