⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c-algo-ip3203.c

📁 PNX8550 I2C总线驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                {                        if (pmsg->flags & I2C_M_TEN)                        {                		    // addr = 10 bit addr, not supported yet                        }                        else                        {                               // addr = 7 bit addr                               addr &= 0x7f;                               addr <<= 1;                        }                }                /*  wr_write handles all master read/write commands, including repeat start (I2C_M_NOSTART)                 */                if (pmsg->flags & I2C_M_RD )                {                        /* read bytes into buffer*/                        rd_buf = pmsg->buf;                        rd_len = pmsg->len;                }                else                {                        /* write bytes from buffer */                        wr_buf = pmsg->buf;                        wr_len = pmsg->len;                }        }        if (num != 0)        {                switch(ret = i2c_write_read(i2c_adap, addr, wr_buf, wr_len, rd_buf, rd_len))                {                case errids_Ok:                        break;                case errids_IsI2cHardwareError:                        num = -1;                        dev_dbg(&i2c_adap->dev, "Hardware error\n");                        IP3203_reset(i2c_adap);                        break;                case errids_IsI2cDeviceError:                        num = -1;                        dev_dbg(&i2c_adap->dev, "Device error\n");                        IP3203_reset(i2c_adap);                        break;                case errids_IsI2cWriteError:                        num = -1;                        dev_dbg(&i2c_adap->dev, "Write error\n");                        IP3203_reset(i2c_adap);                        break;                default:                        num = -1;                        dev_dbg(&i2c_adap->dev, "Error Unkonwn\n");                        IP3203_reset(i2c_adap);                        break;                }        }        return num;}static int algo_control(struct i2c_adapter *i2c_adap, unsigned int cmd, unsigned long arg){        struct I2cBusObject * busptr =  (struct I2cBusObject *)i2c_adap->algo_data;        switch (cmd)        {        case I2C_SET_SLAVE_ADDRESS:                if (busptr->slv_enabled)                        return -EBUSY;                else                {                        write_IP3203_I2CSLA( busptr, I2CADDRESS( arg ));/* >> 1 */; /* 7 bits address, No General call support */dev_dbg(&i2c_adap->dev, "Set Own adress to %x\n", read_IP3203_I2CSLA(busptr));                }                break;        case I2C_SET_SLAVE_ENABLE:                if (arg)                {                        if( !busptr->slv_enabled )                        {                               unsigned int len = (unsigned int)arg;                               len++;  // Need an extra byte for the length                               busptr->slv_buf = kmalloc(len, GFP_KERNEL);                               if (NULL != busptr->slv_buf)                               {                                       busptr->slv_usr_notify = &i2c_adap->fasync;                                       busptr->slv_bufindex = 1;                                       busptr->slv_buflen = 0; // todo : slave transmitter, but we can only reveive                                       busptr->slv_bufsize = len;                                       busptr->slv_enabled = TRUE;                                       AAOUT( busptr, 1 ); /* ACK bit will be returned after slave address reception */                                       dev_dbg(&i2c_adap->dev, "Enable Slave\n");                               }                               else return -ENOMEM;                        }                        else return -EBUSY;                }                else                {                        busptr->slv_usr_notify = NULL;                        busptr->slv_bufsize    = 0;                        AAOUT( busptr, 0 ); /* ACK will not be sent after slave address reception */                        busptr->slv_enabled = FALSE;                        if (NULL != busptr->slv_buf)                        {                            kfree(busptr->slv_buf);  // kfree returns void, no check needed                        }                        busptr->slv_bufindex  = 0;                        busptr->slv_buflen    = 0;dev_dbg(&i2c_adap->dev, "Disable Slave\n");                }                break;      case I2C_GET_SLAVE_DATA:                {                        unsigned long ret;                        unsigned char * user_data = (unsigned char *)arg;                        unsigned char nr_of_bytes = busptr->slv_bufindex -1;                        busptr->slv_buf[0] = nr_of_bytes;                        ret = copy_to_user(user_data, busptr->slv_buf, busptr->slv_bufindex);                        busptr->slv_bufindex = 1;                        if (busptr->slv_enabled == TRUE)                        {                                AAOUT( busptr, 1);  /* ACK bit will be returned after slave address reception */                        }                        if (0 == busptr->slv_buf[0])                        {                                return -ENODATA;                        }                }                break;        }        return 0;}static u32 IP3203_func(struct i2c_adapter *adap){        return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |               I2C_FUNC_PROTOCOL_MANGLING;}/* -----exported algorithm data: -------------------------------------  */static struct i2c_algorithm IP3203_algo_0 = {        .name = "IP3203 dev0",        .id = I2C_ALGO_EXP,	    .master_xfer = IP3203_xfer,        .algo_control = algo_control,                   /* ioctl                */        .functionality = IP3203_func,                     /* functionality        */};static struct i2c_algorithm IP3203_algo_1 = {        .name = "IP3203 dev1",        .id = I2C_ALGO_EXP,        .master_xfer = IP3203_xfer,        .algo_control = algo_control,        .functionality = IP3203_func,};static struct i2c_algorithm * IP3203_algo[NR_I2C_DEVICES] = { &IP3203_algo_0, &IP3203_algo_1 };/* * registering functions to load algorithms at runtime */int i2c_IP3203_add_bus(int device, struct i2c_adapter * i2c_adap){        int res;        dev_dbg(&i2c_adap->dev, "i2c-algo-IP3203.o: i2c IP3203 algorithm module\n");        DEB2(dev_dbg(&i2c_adap->dev, "i2c-algo-viper.o: hw routines for %s registered.\n", i2c_adap->name));        /* register new adapter to i2c module... */        i2c_adap->algo = IP3203_algo[device];        i2c_adap->id |= i2c_adap->algo->id;        i2c_adap->timeout = 100;            /* default values, should       */        i2c_adap->retries = 3;              /* be replaced by defines       */        dev_dbg(&i2c_adap->dev, "Initialise IP3203 device %d\n", device);        IP3203_init(i2c_adap, device);        if ((res = i2c_add_adapter(i2c_adap)) < 0)        {                dev_dbg(&i2c_adap->dev, "i2c-algo-IP3203 %d: Unable to register with I2C\n", device);                return -ENODEV;        }        dev_dbg(&i2c_adap->dev, "add adapter %d returned %x\n", device, res);        /* Todo : scan bus */        return 0;}int i2c_IP3203_del_bus(struct i2c_adapter *i2c_adap){        struct I2cBusObject *busptr;        int device;        int res;        for( device = 0; device < NR_I2C_DEVICES; device++ )        {                dev_dbg(&i2c_adap->dev, "exit bus %x\n", device);                busptr = &IP3203_i2cbus[device];                DISABLE_I2C_INTERRUPT( busptr );                DISABLE_I2C_CONTROLLER( busptr ); /* Disable I2C controller */                if (busptr->slv_enabled)                {                        busptr->slv_usr_notify = NULL;                        busptr->slv_bufsize    = 0;                        AAOUT( busptr, 0 ); /* ACK will not be sent after slave address reception */                        busptr->slv_enabled = FALSE;                        if (NULL != busptr->slv_buf)                        {                                kfree(busptr->slv_buf); // kfree returns void, no check needed                        }                        busptr->slv_bufindex  = 0;                        busptr->slv_buflen    = 0;                }                disable_irq(busptr->int_pin);   /* Enable i2c interrupt in Interrupt controller */                free_irq(busptr->int_pin, (void *)&IP3203_i2cbus[device]); // free_irq returns void, no check needed                enable_irq(busptr->int_pin);   /* Enable i2c interrupt in Interrupt controller */#ifdef USE_DMA                kfree(busptr->dma_bufptr); // kfree returns void, no check needed#endif                if ((res = i2c_del_adapter(i2c_adap)) < 0)                        return res;                DEB2(dev_dbg(&i2c_adap->dev, "i2c-algo-IP3203.o: adapter unregistered: %s\n",i2c_adap->name));        }        return 0;}static struct i2c_adapter IP3203_ops_0 = {       .name = "IP3203 0",                        // name       .id = I2C_HIGH_PERFORMANCE_PORT_1,                // id       .algo_data = &IP3203_i2cbus[0], // algo_data};static struct i2c_adapter IP3203_ops_1 = {       .name = "IP3203 1",       .id = I2C_HIGH_PERFORMANCE_PORT_2,       .algo_data = &IP3203_i2cbus[1], // algo_data};static struct i2c_adapter * IP3203_ops[NR_I2C_DEVICES] = { &IP3203_ops_0, &IP3203_ops_1 };int __init i2c_algo_IP3203_init (void){        printk(/* KERN_INFO,*/ "i2c-algo-IP3203.o: i2c IP3203 algorithm module\n");        int device;        for (device = 0; device < NR_I2C_DEVICES; device++)        {                if (i2c_IP3203_add_bus(device, IP3203_ops[device]) < 0)                {                        printk(/* KERN_INFO,*/"i2c-algo-IP3203 %d: Unable to register with I2C\n", device);                        return -ENODEV;                }        }        return 0;}void __exit i2c_algo_IP3203_exit(void){        struct I2cBusObject *busptr;        int device;        for( device = 0; device < NR_I2C_DEVICES; device++ )        {                printk(/* KERN_INFO, */"exit bus %x\n", device);                busptr = &IP3203_i2cbus[device];                DISABLE_I2C_INTERRUPT( busptr );                DISABLE_I2C_CONTROLLER( busptr ); /* Disable I2C controller */                if (busptr->slv_enabled)                {                        busptr->slv_usr_notify = NULL;                        busptr->slv_bufsize    = 0;                        AAOUT( busptr, 0 ); /* ACK will not be sent after slave address reception */                        busptr->slv_enabled = FALSE;                        if (NULL != busptr->slv_buf)                        {                                kfree(busptr->slv_buf); // kfree returns void, no check needed                        }                        busptr->slv_bufindex  = 0;                        busptr->slv_buflen    = 0;                }                disable_irq(busptr->int_pin);   /* Enable i2c interrupt in Interrupt controller */                free_irq(busptr->int_pin, (void *)&IP3203_i2cbus[device]); // free_irq returns void, no check needed                enable_irq(busptr->int_pin);   /* Enable i2c interrupt in Interrupt controller */#ifdef USE_DMA                kfree(busptr->dma_bufptr); // kfree returns void, no check needed#endif                i2c_IP3203_del_bus(IP3203_ops[device]);        }}MODULE_AUTHOR("Willem van Beek <willem.van.beek@philips.com>");MODULE_DESCRIPTION("I2C-Bus adapter routines for IP3203");MODULE_LICENSE("GPL");/* Called when module is loaded or when kernel is initialized. * If MODULES is defined when this file is compiled, then this function will * resolve to init_module (the function called when insmod is invoked for a * module).  Otherwise, this function is called early in the boot, when the * kernel is intialized.  Check out /include/init.h to see how this works. */subsys_initcall(i2c_algo_IP3203_init);/* Resolves to module_cleanup when MODULES is defined. */module_exit(i2c_algo_IP3203_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -