Changeset 1318

Show
Ignore:
Timestamp:
02/11/02 00:15:12 (7 years ago)
Author:
mds
Message:

(mds)
From: Aurelien Jarno <aurelien@aurel32.net>

Hello,

I have to use the pcf8574 chip with my I2C interface, however, the pcf8574
drivers in lm-sensors is a bit basic. It supposes the pin P1 is used as an
input and the others pin as outputs.

Attached is a patch which corrects that, providing to files in /proc
interface, one for writting, the other for reading. It also modifies a bit
the driver to support the pcf8574a (it is a pcf8574 with a different address
range), and add a documentation file in doc/chips.

The patch also includes some cosmetic changes in the pcf8591 driver I wrote
previously, that is to say it modify the chip name in some places I had
forgotten to change when I made a copy/paste from another driver.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lm-sensors/trunk/CHANGES

    r1313 r1318  
    1919 
    20202.6.3 (2002????) 
     21  Chip modules (most): Allow THIS_MODULE definition for kernels 2.2.18+ 
    2122  File doc/chips/it87: add more temp_type help 
    2223  File sensors.conf.eg: Un-ignore it87 in8, temp3, fan3; 
     
    3536  Module i2c-i810: Add support for 810E 
    3637  Module i2c-piix4: Check for uninitialized base address 
     38  Module i2c-sis5595: Blacklist 735 
    3739  Module i2c-viapro: Check for uninitialized base address 
    3840  Module gl518sm: Standardize /proc entries in0-3 
    3941  Module lm87: Fix in0, in1, in5 initial limits; ain[1,2] -> in[6,7]; 
    4042               fan -> fan1; fix temp2 limit writes 
     43  Module pcf8574: Add support for PCF8574A; /proc interface changed 
    4144  Module pcf8591: new 
     45  Module sis5595: Blacklist 735 
    4246  Module w83781d: Add W83697HF support; allow force_subclients parameter 
    4347                  for Tyan 2460 
  • lm-sensors/trunk/doc/chips/SUMMARY

    r1307 r1318  
    163163        Matrix Orbital LCD displays 
    164164 
    165 pcf8574 
     165pcf8574 & pcf8574a 
    166166        Simple eight-bit parallel I/O 
    167167 
  • lm-sensors/trunk/kernel/chips/pcf8574.c

    r1317 r1318  
    6262/* Addresses to scan */ 
    6363static unsigned short normal_i2c[] = { SENSORS_I2C_END }; 
    64 static unsigned short normal_i2c_range[] = { 0x20, 0x27, SENSORS_I2C_END }; 
     64static unsigned short normal_i2c_range[] = { 0x20, 0x27, 0x38, 0x3f, SENSORS_I2C_END }; 
    6565static unsigned int normal_isa[] = { SENSORS_ISA_END }; 
    6666static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; 
    6767 
    6868/* Insmod parameters */ 
    69 SENSORS_INSMOD_1(pcf8574); 
     69SENSORS_INSMOD_2(pcf8574, pcf8574a); 
    7070 
    7171/* The PCF8574 registers */ 
     
    7474 
    7575/* Initial values */ 
    76 #define PCF8574_INIT 0         /* Both off */ 
     76#define PCF8574_INIT 255       /* All outputs on (input mode) */ 
    7777 
    7878/* Each client has this additional data */ 
     
    8484        unsigned long last_updated;     /* In jiffies */ 
    8585 
    86         u8 status;             /* Register values */ 
     86        u8 read, write;                /* Register values */ 
    8787}; 
    8888 
     
    107107static void pcf8574_inc_use(struct i2c_client *client); 
    108108static void pcf8574_dec_use(struct i2c_client *client); 
    109 static void pcf8574_status(struct i2c_client *client, int operation, 
     109static void pcf8574_read(struct i2c_client *client, int operation, 
     110                                       int ctl_name, int *nrels_mag, long *results); 
     111static void pcf8574_write(struct i2c_client *client, int operation, 
    110112                                       int ctl_name, int *nrels_mag, long *results); 
    111113static void pcf8574_update_client(struct i2c_client *client); 
    112  
     114static void pcf8574_init_client(struct i2c_client *client); 
    113115 
    114116/* This is the driver that will be inserted */ 
     
    130132   when a new copy is allocated. */ 
    131133static ctl_table pcf8574_dir_table_template[] = { 
    132         {PCF8574_SYSCTL_STAT, "status", NULL, 0, 0644, NULL, &i2c_proc_real, 
    133          &i2c_sysctl_real, NULL, &pcf8574_status}, 
     134        {PCF8574_SYSCTL_READ, "read", NULL, 0, 0444, NULL, &i2c_proc_real, 
     135         &i2c_sysctl_real, NULL, &pcf8574_read}, 
     136        {PCF8574_SYSCTL_WRITE, "write", NULL, 0, 0644, NULL, &i2c_proc_real, 
     137         &i2c_sysctl_real, NULL, &pcf8574_write}, 
    134138        {0} 
    135139}; 
     
    191195           impossible to detect! Stupid chip. */ 
    192196 
    193         /* Determine the chip type - only one kind supported! */ 
    194         if (kind <= 0) 
    195                 kind = pcf8574; 
     197        /* Determine the chip type */ 
     198        if (kind <= 0) { 
     199                if (address >= 0x20 && address <= 0x27) 
     200                        kind = pcf8574; 
     201                else if (address >= 0x38 && address <= 0x3f) 
     202                        kind = pcf8574a; 
     203                else goto ERROR1; 
     204        } 
    196205 
    197206        if (kind == pcf8574) { 
    198207                type_name = "pcf8574"; 
    199208                client_name = "PCF8574 chip"; 
     209        } else 
     210        if (kind == pcf8574a) { 
     211                type_name = "pcf8574a"; 
     212                client_name = "PCF8574A chip"; 
    200213        } else { 
    201214#ifdef DEBUG 
     
    226239        data->sysctl_id = i; 
    227240 
     241        /* Initialize the PCF8574 chip */ 
     242        pcf8574_init_client(new_client); 
    228243        return 0; 
    229244 
     
    282297} 
    283298 
     299/* Called when we have found a new PCF8574. */ 
     300void pcf8574_init_client(struct i2c_client *client) 
     301{ 
     302        struct pcf8574_data *data = client->data; 
     303        data->write = PCF8574_INIT; 
     304        i2c_smbus_write_byte(client, data->write); 
     305} 
     306 
    284307 
    285308void pcf8574_update_client(struct i2c_client *client) 
     
    296319#endif 
    297320 
    298                 data->status = i2c_smbus_read_byte(client);  
     321                data->read = i2c_smbus_read_byte(client);  
    299322                data->last_updated = jiffies; 
    300323                data->valid = 1; 
     
    305328 
    306329 
    307 void pcf8574_status(struct i2c_client *client, int operation, 
     330void pcf8574_read(struct i2c_client *client, int operation, 
    308331                    int ctl_name, int *nrels_mag, long *results) 
    309332{ 
    310         u8      tmpstatus;  
    311  
    312333        struct pcf8574_data *data = client->data; 
    313334        if (operation == SENSORS_PROC_REAL_INFO) 
     
    315336        else if (operation == SENSORS_PROC_REAL_READ) { 
    316337                pcf8574_update_client(client); 
    317                 tmpstatus = data->status;                
    318                 tmpstatus = (tmpstatus & 0xf0) >> 4; 
    319                 results[0] = tmpstatus;  
    320                 tmpstatus = data->status;                
    321                 tmpstatus &= 0x0f; 
    322                 results[1] = tmpstatus;  
    323                 *nrels_mag = 2; 
     338                results[0] = data->read; 
     339                *nrels_mag = 1; 
     340        }   
     341
     342void pcf8574_write(struct i2c_client *client, int operation, 
     343                    int ctl_name, int *nrels_mag, long *results) 
     344
     345        u8      tmpstatus;  
     346 
     347        struct pcf8574_data *data = client->data; 
     348        if (operation == SENSORS_PROC_REAL_INFO) 
     349                *nrels_mag = 0; 
     350        else if (operation == SENSORS_PROC_REAL_READ) { 
     351                results[0] = data->write;  
     352                *nrels_mag = 1; 
    324353        } else if (operation == SENSORS_PROC_REAL_WRITE) { 
    325                 if (*nrels_mag >= 1) { 
    326                         data->status = (data->status & 2) | results[0]; 
    327                         i2c_smbus_write_byte(client, data->status); 
     354                if (*nrels_mag = 1) { 
     355                        data->write = results[0]; 
     356                        i2c_smbus_write_byte(client, data->write); 
    328357                } 
    329358        } 
    330359} 
     360 
    331361 
    332362int __init sensors_pcf8574_init(void) 
     
    367397 
    368398MODULE_AUTHOR 
    369     ("Frodo Looijaard <frodol@dds.nl>, Philip Edelbrock <phil@netroedge.com and Dan Eaton <dan.eaton@rocketlogix.com>"); 
     399    ("Frodo Looijaard <frodol@dds.nl>, Philip Edelbrock <phil@netroedge.com>, Dan Eaton <dan.eaton@rocketlogix.com> and Aurelien Jarno <aurelien@aurel32.net>"); 
    370400MODULE_DESCRIPTION("PCF8574 driver"); 
    371401 
  • lm-sensors/trunk/kernel/chips/pcf8591.c

    r1253 r1318  
    201201        if (i2c_is_isa_adapter(adapter)) { 
    202202                printk 
    203                     (KERN_ERR "pcf8574.o: pcf8574_detect called for an ISA bus adapter?!?\n"); 
     203                    (KERN_ERR "pcf8591.o: pcf8591_detect called for an ISA bus adapter?!?\n"); 
    204204                return 0; 
    205205        } 
     
    225225        new_client->flags = 0; 
    226226 
    227         /* Now, we would do the remaining detection. But the PCF8574 is plainly 
     227        /* Now, we would do the remaining detection. But the PCF8591 is plainly 
    228228           impossible to detect! Stupid chip. */ 
    229229 
  • lm-sensors/trunk/kernel/include/sensors.h

    r1310 r1318  
    432432#define LM87_ALARM_TEMP3_FAULT 0x08000 
    433433 
    434 #define PCF8574_SYSCTL_STAT 1000 
     434#define PCF8574_SYSCTL_READ     1000 
     435#define PCF8574_SYSCTL_WRITE    1001 
    435436 
    436437#define MTP008_SYSCTL_IN0       1000    /* Volts * 100 */