Changeset 3877

Show
Ignore:
Timestamp:
12/20/03 00:49:29 (9 years ago)
Author:
mds
Message:

add emulated block read and block process call support;

patch as received from: Liu Tao <lt@…>
My tweaks to follow


Here is the patch to support SMBus Block Read and SMBus Block Process Call
protocols under I2C emulation. It adds the I2C_M_RECV_LEN flag.

To support the two protocols, an algorithm driver should handle the
I2C_M_RECV_LEN flag in its master_xfer routin, and return
I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_READ_BLOCK_DATA or
I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL
in its functionality routin.

Existing algorithm drivers won't be affected by this patch.

-- Regards, Liu Tao

Location:
i2c/trunk/kernel
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • i2c/trunk/kernel/i2c-algo-bit.c

    r3872 r3877  
    379379        char *temp = msg->buf; 
    380380        int count = msg->len; 
     381        int recv_len = 0; 
     382 
     383        /* Receive [Count] for I2C_SMBUS_BLOCK_DATA or I2C_SMBUS_BLOCK_PROC_CALL protocol */ 
     384        if (msg->flags & I2C_M_RECV_LEN) 
     385                recv_len = 1; 
    381386 
    382387        while (count > 0) { 
     
    391396                } 
    392397 
     398                if (recv_len) { 
     399                        recv_len = 0; 
     400                        /* [Count] should be between 1 and 31 (I2C_SMBUS_BLOCK_MAX - 1). */ 
     401                        if (inval > 0 && inval < I2C_SMBUS_BLOCK_MAX) { 
     402                                count = inval + 1;      /* plus one for [Count] itself */ 
     403                                msg->len = count; 
     404                        } else { 
     405                                printk(KERN_ERR "i2c-algo-bit.o: readbytes: bad block count (%d).\n", inval); 
     406                                break; 
     407                        } 
     408                } 
     409                 
    393410                if ( count > 1 ) {              /* send ack */ 
    394411                        sdalo(adap); 
     
    518535{ 
    519536        return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |  
    520                I2C_FUNC_PROTOCOL_MANGLING; 
     537               I2C_FUNC_PROTOCOL_MANGLING | 
     538               I2C_FUNC_SMBUS_BLOCK_PROC_CALL | 
     539               I2C_FUNC_SMBUS_READ_BLOCK_DATA; 
    521540} 
    522541 
  • i2c/trunk/kernel/i2c-core.c

    r3872 r3877  
    12601260        case I2C_SMBUS_BLOCK_DATA_PEC: 
    12611261                if (read_write == I2C_SMBUS_READ) { 
    1262                         printk(KERN_ERR "i2c-core.o: Block read not supported " 
    1263                                "under I2C emulation!\n"); 
    1264                         return -1; 
     1262                        /* I2C_FUNC_SMBUS_EMUL doesn't include I2C_FUNC_SMBUS_READ_BLOCK_DATA */ 
     1263                        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BLOCK_DATA)) { 
     1264                                printk(KERN_ERR "i2c-core.o: Block read not supported " 
     1265                                       "under I2C emulation!\n"); 
     1266                                return -1; 
     1267                        } 
     1268                        /* set send message */ 
     1269                        msg[0].len = 1; 
     1270                        /* set recv message */ 
     1271                        msg[1].flags |= I2C_M_RECV_LEN; 
     1272                        msg[1].len = I2C_SMBUS_BLOCK_MAX + 1; 
     1273                        if (size == I2C_SMBUS_BLOCK_DATA_PEC) 
     1274                                msg[1].len++; 
    12651275                } else { 
    12661276                        msg[0].len = data->block[0] + 2; 
     
    12791289        case I2C_SMBUS_BLOCK_PROC_CALL: 
    12801290        case I2C_SMBUS_BLOCK_PROC_CALL_PEC: 
    1281                 printk(KERN_ERR "i2c-core.o: Block process call not supported " 
    1282                        "under I2C emulation!\n"); 
    1283                 return -1; 
     1291                /* I2C_FUNC_SMBUS_EMUL doesn't include I2C_FUNC_SMBUS_BLOCK_PROC_CALL */ 
     1292                if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BLOCK_PROC_CALL)) { 
     1293                        printk(KERN_ERR "i2c-core.o: adapter doesn't support block process call!\n"); 
     1294                        return -1; 
     1295                } 
     1296 
     1297                /* Another special case */ 
     1298                num = 2; 
     1299                read_write = I2C_SMBUS_READ; 
     1300                 
     1301                /* set send message */ 
     1302                msg[0].len = data->block[0] + 2; 
     1303                if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { 
     1304                        printk(KERN_ERR "i2c-core.o: smbus_access called with " 
     1305                                "invalid block write size (%d)\n", data->block[0]); 
     1306                        return -1; 
     1307                } 
     1308                for (i = 1; i <= msg[0].len; i++) 
     1309                        msgbuf0[i] = data->block[i-1]; 
     1310                 
     1311                /* set recv message */ 
     1312                msg[1].flags |= I2C_M_RECV_LEN; 
     1313                msg[1].len = I2C_SMBUS_BLOCK_MAX + 1; 
     1314                if (size == I2C_SMBUS_BLOCK_PROC_CALL_PEC) 
     1315                        msg[1].len++; 
     1316                break; 
    12841317        case I2C_SMBUS_I2C_BLOCK_DATA: 
    12851318                if (read_write == I2C_SMBUS_READ) { 
     
    13241357                                        data->block[i+1] = msgbuf1[i]; 
    13251358                                break; 
     1359                        case I2C_SMBUS_BLOCK_DATA: 
     1360                        case I2C_SMBUS_BLOCK_DATA_PEC: 
     1361                        case I2C_SMBUS_BLOCK_PROC_CALL: 
     1362                        case I2C_SMBUS_BLOCK_PROC_CALL_PEC: 
     1363                                for (i = 0; i < I2C_SMBUS_BLOCK_MAX + 2; i++) 
     1364                                        data->block[i] = msgbuf1[i]; 
     1365                                break; 
    13261366                } 
    13271367        return 0; 
  • i2c/trunk/kernel/i2c.h

    r3871 r3877  
    362362#define I2C_M_IGNORE_NAK        0x1000 
    363363#define I2C_M_NO_RD_ACK         0x0800 
     364#define I2C_M_RECV_LEN          0x0400 
    364365        __u16 len;              /* msg length                           */ 
    365366        __u8 *buf;              /* pointer to msg data                  */