source: trunk/target/linux/cns3xxx/patches-3.0/110-gateworks_gsp_support.patch @ 27328

Last change on this file since 27328 was 27328, checked in by kaloz, 5 years ago

[cns3xxx]: preliminary 3.0 support

File size: 10.5 KB
  • drivers/hwmon/Kconfig

    a b config SENSORS_GL520SM 
    401401          This driver can also be built as a module.  If so, the module 
    402402          will be called gl520sm. 
    403403 
     404config SENSORS_GSP 
     405        tristate "Gateworks System Peripheral" 
     406        depends on I2C && EXPERIMENTAL 
     407        help 
     408          If you say yes here you get support for the Gateworks System Peripherals. 
     409 
     410          This driver can also be built as a module. If so, the module 
     411          will be called gsp. 
     412 
    404413config SENSORS_GPIO_FAN 
    405414        tristate "GPIO fan" 
    406415        depends on GENERIC_GPIO 
  • drivers/hwmon/Makefile

    a b obj-$(CONFIG_SENSORS_W83L785TS) += w83l7 
    118118obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o 
    119119obj-$(CONFIG_SENSORS_WM831X)    += wm831x-hwmon.o 
    120120obj-$(CONFIG_SENSORS_WM8350)    += wm8350-hwmon.o 
     121obj-$(CONFIG_SENSORS_GSP)       += gsp.o 
    121122 
    122123# PMBus drivers 
    123124obj-$(CONFIG_PMBUS)             += pmbus_core.o 
  • new file drivers/hwmon/gsp.c

    - +  
     1/* 
     2 * A hwmon driver for the Gateworks System Peripheral 
     3 * Copyright (C) 2009 Gateworks Corporation 
     4 * 
     5 * Author: Chris Lang <clang@gateworks.com> 
     6 * 
     7 * This program is free software; you can redistribute it and/or modify 
     8 * it under the terms of the GNU General Public License, 
     9 * as published by the Free Software Foundation - version 2. 
     10 */ 
     11 
     12#include <linux/module.h> 
     13#include <linux/i2c.h> 
     14#include <linux/hwmon.h> 
     15#include <linux/hwmon-sysfs.h> 
     16#include <linux/err.h> 
     17#include <linux/slab.h> 
     18 
     19#define DRV_VERSION "0.2" 
     20 
     21enum chips { gsp }; 
     22 
     23/* AD7418 registers */ 
     24#define GSP_REG_TEMP_IN         0x00 
     25#define GSP_REG_VIN             0x02 
     26#define GSP_REG_3P3             0x05 
     27#define GSP_REG_BAT             0x08 
     28#define GSP_REG_5P0             0x0b 
     29#define GSP_REG_CORE            0x0e 
     30#define GSP_REG_CPU1            0x11 
     31#define GSP_REG_CPU2            0x14 
     32#define GSP_REG_DRAM            0x17 
     33#define GSP_REG_EXT_BAT         0x1a 
     34#define GSP_REG_IO1             0x1d 
     35#define GSP_REG_IO2             0x20 
     36#define GSP_REG_PCIE            0x23 
     37#define GSP_REG_CURRENT         0x26 
     38#define GSP_FAN_0               0x2C 
     39#define GSP_FAN_1               0x2E 
     40#define GSP_FAN_2               0x30 
     41#define GSP_FAN_3               0x32 
     42#define GSP_FAN_4               0x34 
     43#define GSP_FAN_5               0x36 
     44 
     45struct gsp_sensor_info { 
     46        const char* name; 
     47        int reg; 
     48}; 
     49 
     50static const struct gsp_sensor_info gsp_sensors[] = { 
     51        {"temp", GSP_REG_TEMP_IN}, 
     52        {"vin", GSP_REG_VIN}, 
     53        {"3p3", GSP_REG_3P3}, 
     54        {"bat", GSP_REG_BAT}, 
     55        {"5p0", GSP_REG_5P0}, 
     56        {"core", GSP_REG_CORE}, 
     57        {"cpu1", GSP_REG_CPU1}, 
     58        {"cpu2", GSP_REG_CPU2}, 
     59        {"dram", GSP_REG_DRAM}, 
     60        {"ext_bat", GSP_REG_EXT_BAT}, 
     61        {"io1", GSP_REG_IO1}, 
     62        {"io2", GSP_REG_IO2}, 
     63        {"pci2", GSP_REG_PCIE}, 
     64        {"current", GSP_REG_CURRENT}, 
     65        {"fan_point0", GSP_FAN_0}, 
     66        {"fan_point1", GSP_FAN_1}, 
     67        {"fan_point2", GSP_FAN_2}, 
     68        {"fan_point3", GSP_FAN_3}, 
     69        {"fan_point4", GSP_FAN_4}, 
     70        {"fan_point5", GSP_FAN_5}, 
     71}; 
     72 
     73struct gsp_data { 
     74        struct device           *hwmon_dev; 
     75        struct attribute_group  attrs; 
     76        enum chips              type; 
     77}; 
     78 
     79static int gsp_probe(struct i2c_client *client, 
     80                        const struct i2c_device_id *id); 
     81static int gsp_remove(struct i2c_client *client); 
     82 
     83static const struct i2c_device_id gsp_id[] = { 
     84        { "gsp", 0 }, 
     85        { } 
     86}; 
     87MODULE_DEVICE_TABLE(i2c, gsp_id); 
     88 
     89static struct i2c_driver gsp_driver = { 
     90        .driver = { 
     91                .name   = "gsp", 
     92        }, 
     93        .probe          = gsp_probe, 
     94        .remove         = gsp_remove, 
     95        .id_table       = gsp_id, 
     96}; 
     97 
     98/* All registers are word-sized, except for the configuration registers. 
     99 * AD7418 uses a high-byte first convention. Do NOT use those functions to 
     100 * access the configuration registers CONF and CONF2, as they are byte-sized. 
     101 */ 
     102static inline int gsp_read(struct i2c_client *client, u8 reg) 
     103{ 
     104        unsigned int adc = 0; 
     105        if (reg == GSP_REG_TEMP_IN || reg > GSP_REG_CURRENT) 
     106        { 
     107                adc |= i2c_smbus_read_byte_data(client, reg); 
     108                adc |= i2c_smbus_read_byte_data(client, reg + 1) << 8; 
     109                return adc; 
     110        } 
     111        else 
     112        { 
     113                adc |= i2c_smbus_read_byte_data(client, reg); 
     114                adc |= i2c_smbus_read_byte_data(client, reg + 1) << 8; 
     115                adc |= i2c_smbus_read_byte_data(client, reg + 2) << 16; 
     116                return adc; 
     117        } 
     118} 
     119 
     120static inline int gsp_write(struct i2c_client *client, u8 reg, u16 value) 
     121{ 
     122        i2c_smbus_write_byte_data(client, reg, value & 0xff); 
     123        i2c_smbus_write_byte_data(client, reg + 1, ((value >> 8) & 0xff)); 
     124        return 1; 
     125} 
     126 
     127static ssize_t show_adc(struct device *dev, struct device_attribute *devattr, 
     128                        char *buf) 
     129{ 
     130        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 
     131        struct i2c_client *client = to_i2c_client(dev); 
     132        return sprintf(buf, "%d\n", gsp_read(client, gsp_sensors[attr->index].reg)); 
     133} 
     134 
     135static ssize_t show_label(struct device *dev, 
     136                        struct device_attribute *devattr, char *buf) 
     137{ 
     138        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 
     139 
     140        return sprintf(buf, "%s\n", gsp_sensors[attr->index].name); 
     141} 
     142 
     143static ssize_t store_fan(struct device *dev, 
     144                        struct device_attribute *devattr, const char *buf, size_t count) 
     145{ 
     146        u16 val; 
     147        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 
     148        struct i2c_client *client = to_i2c_client(dev); 
     149        val = simple_strtoul(buf, NULL, 10); 
     150        gsp_write(client, gsp_sensors[attr->index].reg, val); 
     151        return count; 
     152} 
     153 
     154static SENSOR_DEVICE_ATTR(temp0_input, S_IRUGO, show_adc, NULL, 0); 
     155static SENSOR_DEVICE_ATTR(temp0_label, S_IRUGO, show_label, NULL, 0); 
     156 
     157static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_adc, NULL, 1); 
     158static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL, 1); 
     159static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_adc, NULL, 2); 
     160static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_label, NULL, 2); 
     161static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 3); 
     162static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_label, NULL, 3); 
     163static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 4); 
     164static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 4); 
     165static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 5); 
     166static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL, 5); 
     167static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_adc, NULL, 6); 
     168static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL, 6); 
     169static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_adc, NULL, 7); 
     170static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL, 7); 
     171static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_adc, NULL, 8); 
     172static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 8); 
     173static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_adc, NULL, 9); 
     174static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 9); 
     175static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_adc, NULL, 10); 
     176static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 10); 
     177static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_adc, NULL, 11); 
     178static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_label, NULL, 11); 
     179static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_adc, NULL, 12); 
     180static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_label, NULL, 12); 
     181static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_adc, NULL, 13); 
     182static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_label, NULL, 13); 
     183 
     184static SENSOR_DEVICE_ATTR(fan0_point0, S_IRUGO | S_IWUSR, show_adc, store_fan, 14); 
     185static SENSOR_DEVICE_ATTR(fan0_point1, S_IRUGO | S_IWUSR, show_adc, store_fan, 15); 
     186static SENSOR_DEVICE_ATTR(fan0_point2, S_IRUGO | S_IWUSR, show_adc, store_fan, 16); 
     187static SENSOR_DEVICE_ATTR(fan0_point3, S_IRUGO | S_IWUSR, show_adc, store_fan, 17); 
     188static SENSOR_DEVICE_ATTR(fan0_point4, S_IRUGO | S_IWUSR, show_adc, store_fan, 18); 
     189static SENSOR_DEVICE_ATTR(fan0_point5, S_IRUGO | S_IWUSR, show_adc, store_fan, 19); 
     190 
     191static struct attribute *gsp_attributes[] = { 
     192        &sensor_dev_attr_temp0_input.dev_attr.attr, 
     193        &sensor_dev_attr_in0_input.dev_attr.attr, 
     194        &sensor_dev_attr_in1_input.dev_attr.attr, 
     195        &sensor_dev_attr_in2_input.dev_attr.attr, 
     196        &sensor_dev_attr_in3_input.dev_attr.attr, 
     197        &sensor_dev_attr_in4_input.dev_attr.attr, 
     198        &sensor_dev_attr_in5_input.dev_attr.attr, 
     199        &sensor_dev_attr_in6_input.dev_attr.attr, 
     200        &sensor_dev_attr_in7_input.dev_attr.attr, 
     201        &sensor_dev_attr_in8_input.dev_attr.attr, 
     202        &sensor_dev_attr_in9_input.dev_attr.attr, 
     203        &sensor_dev_attr_in10_input.dev_attr.attr, 
     204        &sensor_dev_attr_in11_input.dev_attr.attr, 
     205        &sensor_dev_attr_in12_input.dev_attr.attr, 
     206 
     207        &sensor_dev_attr_temp0_label.dev_attr.attr, 
     208        &sensor_dev_attr_in0_label.dev_attr.attr, 
     209        &sensor_dev_attr_in1_label.dev_attr.attr, 
     210        &sensor_dev_attr_in2_label.dev_attr.attr, 
     211        &sensor_dev_attr_in3_label.dev_attr.attr, 
     212        &sensor_dev_attr_in4_label.dev_attr.attr, 
     213        &sensor_dev_attr_in5_label.dev_attr.attr, 
     214        &sensor_dev_attr_in6_label.dev_attr.attr, 
     215        &sensor_dev_attr_in7_label.dev_attr.attr, 
     216        &sensor_dev_attr_in8_label.dev_attr.attr, 
     217        &sensor_dev_attr_in9_label.dev_attr.attr, 
     218        &sensor_dev_attr_in10_label.dev_attr.attr, 
     219        &sensor_dev_attr_in11_label.dev_attr.attr, 
     220        &sensor_dev_attr_in12_label.dev_attr.attr, 
     221 
     222        &sensor_dev_attr_fan0_point0.dev_attr.attr, 
     223        &sensor_dev_attr_fan0_point1.dev_attr.attr, 
     224        &sensor_dev_attr_fan0_point2.dev_attr.attr, 
     225        &sensor_dev_attr_fan0_point3.dev_attr.attr, 
     226        &sensor_dev_attr_fan0_point4.dev_attr.attr, 
     227        &sensor_dev_attr_fan0_point5.dev_attr.attr, 
     228        NULL 
     229}; 
     230 
     231 
     232static int gsp_probe(struct i2c_client *client, 
     233                         const struct i2c_device_id *id) 
     234{ 
     235        struct i2c_adapter *adapter = client->adapter; 
     236        struct gsp_data *data; 
     237        int err; 
     238 
     239        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 
     240                                        I2C_FUNC_SMBUS_WORD_DATA)) { 
     241                err = -EOPNOTSUPP; 
     242                goto exit; 
     243        } 
     244 
     245        if (!(data = kzalloc(sizeof(struct gsp_data), GFP_KERNEL))) { 
     246                err = -ENOMEM; 
     247                goto exit; 
     248        } 
     249 
     250        i2c_set_clientdata(client, data); 
     251 
     252        data->type = id->driver_data; 
     253 
     254        switch (data->type) { 
     255        case 0: 
     256                data->attrs.attrs = gsp_attributes; 
     257                break; 
     258        } 
     259 
     260        dev_info(&client->dev, "%s chip found\n", client->name); 
     261 
     262        /* Register sysfs hooks */ 
     263        if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) 
     264                goto exit_free; 
     265 
     266        data->hwmon_dev = hwmon_device_register(&client->dev); 
     267        if (IS_ERR(data->hwmon_dev)) { 
     268                err = PTR_ERR(data->hwmon_dev); 
     269                goto exit_remove; 
     270        } 
     271 
     272        return 0; 
     273 
     274exit_remove: 
     275        sysfs_remove_group(&client->dev.kobj, &data->attrs); 
     276exit_free: 
     277        kfree(data); 
     278exit: 
     279        return err; 
     280} 
     281 
     282static int gsp_remove(struct i2c_client *client) 
     283{ 
     284        struct gsp_data *data = i2c_get_clientdata(client); 
     285        hwmon_device_unregister(data->hwmon_dev); 
     286        sysfs_remove_group(&client->dev.kobj, &data->attrs); 
     287        kfree(data); 
     288        return 0; 
     289} 
     290 
     291static int __init gsp_init(void) 
     292{ 
     293        return i2c_add_driver(&gsp_driver); 
     294} 
     295 
     296static void __exit gsp_exit(void) 
     297{ 
     298        i2c_del_driver(&gsp_driver); 
     299} 
     300 
     301module_init(gsp_init); 
     302module_exit(gsp_exit); 
     303 
     304MODULE_AUTHOR("Chris Lang <clang@gateworks.com>"); 
     305MODULE_DESCRIPTION("GSP HWMON driver"); 
     306MODULE_LICENSE("GPL"); 
     307MODULE_VERSION(DRV_VERSION); 
     308 
Note: See TracBrowser for help on using the repository browser.