hwmon: add support for w83667hg

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Gong Jun,

On Sun, Nov 30, 2008 at 11:31 PM,  <JGong at nuvoton.com> wrote:
> Dear David,
>
>>The last two reads are identical to the ones in the for loop. Can this
>>code be moved to the for loop instead of skipping it there and then
>>reading it after?
>
> Thanks I've fixed it. Here is the updated one.
>
> Best regards,
> Gong Jun
>
> Signed-off-by: Gong Jun <JGong at nuvoton.com>

Looks good.

Signed-off-by: David Hubbard <david.c.hubbard at gmail.com>

> ---
>  w83627ehf.c |  122 +++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 82 insertions(+), 40 deletions(-)
> ---
> --- w83627ehf.c.orig    2008-11-26 11:13:12.000000000 +0800
> +++ w83627ehf.c 2008-11-27 11:26:01.000000000 +0800
> @@ -36,6 +36,7 @@
>     w83627ehf   10      5       4       3      0x8850 0x88    0x5ca3
>                                                0x8860 0xa1
>     w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
> +    w83667hg     9      5       3       3      0xa510 0xc1    0x5ca3
>  */
>
>  #include <linux/module.h>
> @@ -51,12 +52,13 @@
>  #include <asm/io.h>
>  #include "lm75.h"
>
> -enum kinds { w83627ehf, w83627dhg };
> +enum kinds { w83627ehf, w83627dhg, w83667hg};
>
>  /* used to set data->name = w83627ehf_device_names[data->sio_kind] */
>  static const char * w83627ehf_device_names[] = {
>        "w83627ehf",
>        "w83627dhg",
> +       "w83667hg",
>  };
>
>  static unsigned short force_id;
> @@ -70,6 +72,7 @@ MODULE_PARM_DESC(force_id, "Override the
>  */
>
>  #define W83627EHF_LD_HWM       0x0b
> +#define W83667HG_LD_VID        0x0d
>
>  #define SIO_REG_LDSEL          0x07    /* Logical device select */
>  #define SIO_REG_DEVID          0x20    /* Device ID (2 bytes) */
> @@ -82,6 +85,7 @@ MODULE_PARM_DESC(force_id, "Override the
>  #define SIO_W83627EHF_ID       0x8850
>  #define SIO_W83627EHG_ID       0x8860
>  #define SIO_W83627DHG_ID       0xa020
> +#define SIO_W83667HG_ID        0xa510
>  #define SIO_ID_MASK            0xFFF0
>
>  static inline void
> @@ -148,6 +152,7 @@ static const u16 W83627EHF_REG_FAN_MIN[]
>                                         (0x555 + (((nr) - 7) * 2)))
>  #define W83627EHF_REG_IN(nr)           ((nr < 7) ? (0x20 + (nr)) : \
>                                         (0x550 + (nr) - 7))
> +#define W83627EHF_REG_IN6_667HG        0x250           // vin6 register for 667hg is 0x250
>
>  #define W83627EHF_REG_TEMP1            0x27
>  #define W83627EHF_REG_TEMP1_HYST       0x3a
> @@ -288,6 +293,7 @@ struct w83627ehf_data {
>        u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
>        u8 pwm_enable[4]; /* 1->manual
>                             2->thermal cruise (also called SmartFan I) */
> +       u8 pwm_num;             /* number of pwm */
>        u8 pwm[4];
>        u8 target_temp[4];
>        u8 tolerance[4];
> @@ -453,6 +459,8 @@ static struct w83627ehf_data *w83627ehf_
>        struct w83627ehf_data *data = dev_get_drvdata(dev);
>        int pwmcfg = 0, tolerance = 0; /* shut up the compiler */
>        int i;
> +       struct w83627ehf_sio_data *sio_data = dev->platform_data;
> +       u8 reg;
>
>        mutex_lock(&data->update_lock);
>
> @@ -463,8 +471,19 @@ static struct w83627ehf_data *w83627ehf_
>
>                /* Measured voltages and limits */
>                for (i = 0; i < data->in_num; i++) {
> -                       data->in[i] = w83627ehf_read_value(data,
> -                                     W83627EHF_REG_IN(i));
> +                       if ((sio_data->kind == w83667hg) && (i == 6)) {
> +                               /* W83667HG, try fix in6 lost problem */
> +                               reg = w83627ehf_read_value(data,
> +                                     W83627EHF_REG_TEMP_CONFIG[1]);
> +                               w83627ehf_write_value(data,
> +                                               W83627EHF_REG_TEMP_CONFIG[1], reg | 0x01);
> +                               data->in[i] = w83627ehf_read_value(data,
> +                                             W83627EHF_REG_IN6_667HG);
> +                               w83627ehf_write_value(data,
> +                                               W83627EHF_REG_TEMP_CONFIG[1], reg);
> +                       } else
> +                               data->in[i] = w83627ehf_read_value(data,
> +                                             W83627EHF_REG_IN(i));
>                        data->in_min[i] = w83627ehf_read_value(data,
>                                          W83627EHF_REG_IN_MIN(i));
>                        data->in_max[i] = w83627ehf_read_value(data,
> @@ -1191,7 +1210,7 @@ static void w83627ehf_device_remove_file
>                device_remove_file(dev, &sda_fan_div[i].dev_attr);
>                device_remove_file(dev, &sda_fan_min[i].dev_attr);
>        }
> -       for (i = 0; i < 4; i++) {
> +       for (i = 0; i < data->pwm_num; i++) {
>                device_remove_file(dev, &sda_pwm[i].dev_attr);
>                device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
>                device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
> @@ -1271,8 +1290,10 @@ static int __devinit w83627ehf_probe(str
>        data->name = w83627ehf_device_names[sio_data->kind];
>        platform_set_drvdata(pdev, data);
>
> -       /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */
> -       data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10;
> +       /* 627EHG and 627EHF have 10 voltage inputs; DHG and 667HG have 9 */
> +       data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
> +       /* 667HG has 3 pwms */
> +       data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4;
>
>        /* Initialize the chip */
>        w83627ehf_init_device(data);
> @@ -1280,44 +1301,59 @@ static int __devinit w83627ehf_probe(str
>        data->vrm = vid_which_vrm();
>        superio_enter(sio_data->sioreg);
>        /* Read VID value */
> -       superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
> -       if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
> -               /* Set VID input sensibility if needed. In theory the BIOS
> -                  should have set it, but in practice it's not always the
> -                  case. We only do it for the W83627EHF/EHG because the
> -                  W83627DHG is more complex in this respect. */
> -               if (sio_data->kind == w83627ehf) {
> -                       en_vrm10 = superio_inb(sio_data->sioreg,
> -                                              SIO_REG_EN_VRM10);
> -                       if ((en_vrm10 & 0x08) && data->vrm == 90) {
> -                               dev_warn(dev, "Setting VID input voltage to "
> -                                        "TTL\n");
> -                               superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
> -                                            en_vrm10 & ~0x08);
> -                       } else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
> -                               dev_warn(dev, "Setting VID input voltage to "
> -                                        "VRM10\n");
> -                               superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
> -                                            en_vrm10 | 0x08);
> -                       }
> -               }
> -
> -               data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA);
> -               if (sio_data->kind == w83627ehf) /* 6 VID pins only */
> -                       data->vid &= 0x3f;
> -
> +       if (sio_data->kind == w83667hg) {
> +               /* W83667HG has different pins for VID input and output, so
> +               we can get the VID input values directly at logical device D
> +               0xe3. */
> +               superio_select(sio_data->sioreg, W83667HG_LD_VID);
> +               data->vid = superio_inb(sio_data->sioreg, 0xe3);
>                err = device_create_file(dev, &dev_attr_cpu0_vid);
>                if (err)
>                        goto exit_release;
>        } else {
> -               dev_info(dev, "VID pins in output mode, CPU VID not "
> -                        "available\n");
> +               superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
> +               if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
> +                       /* Set VID input sensibility if needed. In theory the BIOS
> +                          should have set it, but in practice it's not always the
> +                          case. We only do it for the W83627EHF/EHG because the
> +                          W83627DHG is more complex in this respect. */
> +                       if (sio_data->kind == w83627ehf) {
> +                               en_vrm10 = superio_inb(sio_data->sioreg,
> +                                                      SIO_REG_EN_VRM10);
> +                               if ((en_vrm10 & 0x08) && data->vrm == 90) {
> +                                       dev_warn(dev, "Setting VID input voltage to "
> +                                                "TTL\n");
> +                                       superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
> +                                                    en_vrm10 & ~0x08);
> +                               } else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
> +                                       dev_warn(dev, "Setting VID input voltage to "
> +                                                "VRM10\n");
> +                                       superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
> +                                                    en_vrm10 | 0x08);
> +                               }
> +                       }
> +
> +                       data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA);
> +                       if (sio_data->kind == w83627ehf) /* 6 VID pins only */
> +                               data->vid &= 0x3f;
> +
> +                       err = device_create_file(dev, &dev_attr_cpu0_vid);
> +                       if (err)
> +                               goto exit_release;
> +               } else {
> +                       dev_info(dev, "VID pins in output mode, CPU VID not "
> +                                "available\n");
> +               }
>        }
>
>        /* fan4 and fan5 share some pins with the GPIO and serial flash */
> -
> -       fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2;
> -       fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6;
> +       if (sio_data->kind == w83667hg) {
> +               fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20;
> +               fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40;
> +       } else {
> +               fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2;
> +               fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6;
> +       }
>        superio_exit(sio_data->sioreg);
>
>        /* It looks like fan4 and fan5 pins can be alternatively used
> @@ -1343,7 +1379,8 @@ static int __devinit w83627ehf_probe(str
>                        goto exit_remove;
>
>        /* if fan4 is enabled create the sf3 files for it */
> -       if (data->has_fan & (1 << 3))
> +       if ((sio_data->kind != w83667hg) &&
> +               (data->has_fan & (1 << 3)))
>                for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
>                        if ((err = device_create_file(dev,
>                                &sda_sf3_arrays_fan4[i].dev_attr)))
> @@ -1371,8 +1408,8 @@ static int __devinit w83627ehf_probe(str
>                                || (err = device_create_file(dev,
>                                        &sda_fan_min[i].dev_attr)))
>                                goto exit_remove;
> -                       if (i < 4 && /* w83627ehf only has 4 pwm */
> -                               ((err = device_create_file(dev,
> +       if(i < data->pwm_num &&
> +                       ((err = device_create_file(dev,
>                                        &sda_pwm[i].dev_attr))
>                                || (err = device_create_file(dev,
>                                        &sda_pwm_mode[i].dev_attr))
> @@ -1441,6 +1478,7 @@ static int __init w83627ehf_find(int sio
>        static const char __initdata sio_name_W83627EHF[] = "W83627EHF";
>        static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
>        static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
> +       static const char __initdata sio_name_W83667HG[] = "W83667HG";
>
>        u16 val;
>        const char *sio_name;
> @@ -1465,6 +1503,10 @@ static int __init w83627ehf_find(int sio
>                sio_data->kind = w83627dhg;
>                sio_name = sio_name_W83627DHG;
>                break;
> +       case SIO_W83667HG_ID:
> +               sio_data->kind = w83667hg;
> +               sio_name = sio_name_W83667HG;
> +               break;
>        default:
>                if (val != 0xffff)
>                        pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n",




[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux