Re: [PATCH] hwmon: Driver for Sensylink CTF2304

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

 



On 4/5/23 06:32, Il Han wrote:
2023년 4월 1일 (토) 오후 11:54, Guenter Roeck <linux@xxxxxxxxxxxx <mailto:linux@xxxxxxxxxxxx>>님이 작성:

    On Fri, Mar 31, 2023 at 10:34:37PM +0900, Il Han wrote:
     > The driver supports the Sensylink CTF2304.
     >

    Please version your patches, and provide change logs. I am not inclined
    to compare this version with the previous version to find out what changed
    besides the API conversion, and I am not inclined to dig through my e-mail
    history to figure out how many versions of this patch have been submitted.

    Please consult
    Documentation/process/submitting-patches.rst
    Documentation/process/submit-checklist.rst
    Documentation/hwmon/submitting-patches.rst

    and follow the guidance in those documents.

    Thanks,
    Guenter


Sorry, I made this patch newly.
I didn't add it to the previous one.

That is not the point. It is still (at least) v2, and the change log
may have been "rewrote from scratch to implement new hwmon API" or similar.
Besides, I doubt that you rewrote the documentation.

I don't want having to deal with v3, v4, v5, each submitted as "new" with
the same claim that it was rewritten from scratch.

Guenter

So you don't have to compare them
Please disregard the previous one.
I will add the next patch to this next time.
 > Thanks,
Il Han

     > Signed-off-by: Il Han <corone.il.han@xxxxxxxxx <mailto:corone.il.han@xxxxxxxxx>>
     > ---
     >  Documentation/hwmon/ctf2304.rst |  41 +++
     >  Documentation/hwmon/index.rst   |   1 +
     >  drivers/hwmon/Kconfig           |  10 +
     >  drivers/hwmon/Makefile          |   1 +
     >  drivers/hwmon/ctf2304.c         | 522 ++++++++++++++++++++++++++++++++
     >  5 files changed, 575 insertions(+)
     >  create mode 100644 Documentation/hwmon/ctf2304.rst
     >  create mode 100644 drivers/hwmon/ctf2304.c
     >
     > diff --git a/Documentation/hwmon/ctf2304.rst b/Documentation/hwmon/ctf2304.rst
     > new file mode 100644
     > index 000000000000..e1584524d612
     > --- /dev/null
     > +++ b/Documentation/hwmon/ctf2304.rst
     > @@ -0,0 +1,41 @@
     > +.. SPDX-License-Identifier: GPL-2.0-or-later
     > +
     > +Kernel driver ctf2304
     > +=====================
     > +
     > +Supported chips:
     > +
     > +  * Sensylink CTF2304
     > +
     > +    Prefix: 'ctf2304'
     > +
     > +    Addresses scanned: -
     > +
     > +    Datasheet:
     > +
     > +Author: Il Han <corone.il.han@xxxxxxxxx <mailto:corone.il.han@xxxxxxxxx>>
     > +
     > +
     > +Description
     > +-----------
     > +
     > +This driver implements support for the Sensylink CTF2304 chip.
     > +
     > +The CTF2304 controls the speeds of up to four fans using four independent
     > +PWM outputs with local and remote temperature and remote voltage sensing.
     > +
     > +
     > +Sysfs entries
     > +-------------
     > +
     > +================== === =======================================================
     > +fan[1-4]_input     RO  fan tachometer speed in RPM
     > +fan[1-4]_target    RW  desired fan speed in RPM
     > +fan[1-4]_div       RW  sets the RPM range of the fan
     > +pwm[1-4]_enable    RW  regulator mode,
     > +                       0=auto temperature mode, 1=manual mode, 2=rpm mode
     > +pwm[1-4]           RW  read: current pwm duty cycle,
     > +                       write: target pwm duty cycle (0-255)
     > +in[0-7]_input      RO  measured output voltage
     > +temp[1-9]_input    RO  measured temperature
     > +================== === =======================================================
     > diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
     > index f1fe75f596a5..a74cd43a3916 100644
     > --- a/Documentation/hwmon/index.rst
     > +++ b/Documentation/hwmon/index.rst
     > @@ -54,6 +54,7 @@ Hardware Monitoring Kernel Drivers
     >     coretemp
     >     corsair-cpro
     >     corsair-psu
     > +   ctf2304
     >     da9052
     >     da9055
     >     dell-smm-hwmon
     > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
     > index 5b3b76477b0e..da9fbb0f8af3 100644
     > --- a/drivers/hwmon/Kconfig
     > +++ b/drivers/hwmon/Kconfig
     > @@ -474,6 +474,16 @@ config SENSORS_CORSAIR_PSU
     >         This driver can also be built as a module. If so, the module
     >         will be called corsair-psu.
     >
     > +config SENSORS_CTF2304
     > +     tristate "Sensylink CTF2304 sensor chip"
     > +     depends on I2C
     > +     help
     > +       If you say yes here you get support for PWM and Fan Controller
     > +       with temperature and voltage sensing.
     > +
     > +       This driver can also be built as a module. If so, the module
     > +       will be called ctf2304.
     > +
     >  config SENSORS_DRIVETEMP
     >       tristate "Hard disk drives with temperature sensors"
     >       depends on SCSI && ATA
     > diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
     > index 88712b5031c8..3742b52f032d 100644
     > --- a/drivers/hwmon/Makefile
     > +++ b/drivers/hwmon/Makefile
     > @@ -60,6 +60,7 @@ obj-$(CONFIG_SENSORS_BT1_PVT)       += bt1-pvt.o
     >  obj-$(CONFIG_SENSORS_CORETEMP)       += coretemp.o
     >  obj-$(CONFIG_SENSORS_CORSAIR_CPRO) += corsair-cpro.o
     >  obj-$(CONFIG_SENSORS_CORSAIR_PSU) += corsair-psu.o
     > +obj-$(CONFIG_SENSORS_CTF2304)        += ctf2304.o
     >  obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
     >  obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
     >  obj-$(CONFIG_SENSORS_DELL_SMM)       += dell-smm-hwmon.o
     > diff --git a/drivers/hwmon/ctf2304.c b/drivers/hwmon/ctf2304.c
     > new file mode 100644
     > index 000000000000..102c41957219
     > --- /dev/null
     > +++ b/drivers/hwmon/ctf2304.c
     > @@ -0,0 +1,522 @@
     > +// SPDX-License-Identifier: GPL-2.0-or-later
     > +/*
     > + * ctf2304.c - Part of lm_sensors, Linux kernel modules for hardware
     > + *             monitoring.
     > + *
     > + * (C) 2023 by Il Han <corone.il.han@xxxxxxxxx <mailto:corone.il.han@xxxxxxxxx>>
     > + */
     > +
     > +#include <linux/err.h>
     > +#include <linux/hwmon.h>
     > +#include <linux/i2c.h>
     > +#include <linux/init.h>
     > +#include <linux/jiffies.h>
     > +#include <linux/module.h>
     > +#include <linux/slab.h>
     > +
     > +/* CTF2304 registers */
     > +#define CTF2304_REG_LOCAL_TEMP               0x00
     > +#define CTF2304_REG_REMOTE_CHANNEL(ch)       (0x01 + (ch))
     > +#define CTF2304_REG_TACH_COUNT(ch)   (0x09 + (ch))
     > +#define CTF2304_REG_FAN_CONFIG1              0x10
     > +#define CTF2304_REG_FAN_CONFIG2              0x11
     > +#define CTF2304_REG_FAN_RPM_CTRL     0x18
     > +#define CTF2304_REG_PWMOUT(ch)               (0x40 + (ch))
     > +#define CTF2304_REG_TARGET_COUNT(ch) (0x44 + (ch))
     > +
     > +/* Fan Configure1 register bits */
     > +#define CTF2304_FAN_CFG1_TRANGE              0x0400
     > +#define CTF2304_FAN_CFG1_MODE_MASK   (0x7)
     > +#define CTF2304_FAN_CFG1_MODE_SHIFT  7
     > +
     > +/* Fan Configure2 register bits */
     > +#define CTF2304_FAN_CFG2_MODE_MASK(ch)       (0x6 << (ch) * 4)
     > +#define CTF2304_FAN_CFG2_MODE_SHIFT(ch)      (1 + (ch) * 4)
     > +#define CTF2304_FAN_CFG2_DCY_MODE    0
     > +#define CTF2304_FAN_CFG2_RPM_MODE    1
     > +#define CTF2304_FAN_CFG2_TEMP_MODE   2
     > +#define CTF2304_FAN_CFG2_MAX_MODE    3
     > +
     > +/* Fan RPM CTRL register bits */
     > +#define CTF2304_FAN_DIV_MASK(ch)     (0x6 << (ch) * 4)
     > +#define CTF2304_FAN_DIV_SHIFT(ch)    (1 + (ch) * 4)
     > +
     > +#define CTF2304_VCC                  3300
     > +
     > +#define FAN_RPM_MIN                  480
     > +#define FAN_RPM_MAX                  1966080
     > +
     > +#define FAN_COUNT_REG_MAX            0xFFF0
     > +
     > +#define TEMP_FROM_REG(reg, tr)               ((tr) ? \
     > +                                      (((((reg) & 0x7FF0) * 1000) >> 8) \
     > +                                       + ((reg) >> 15) ? -64000 : 0) : \
     > +                                      (((reg) * 1000) >> 8))
     > +#define VOLT_FROM_REG(reg, fs)               ((((reg) >> 4) * (fs)) >> 12)
     > +#define DIV_FROM_REG(reg)            (1 << (reg))
     > +#define DIV_TO_REG(div)                      ((div == 8) ? 0x3 : \
     > +                                      (div == 4) ? 0x2 : \
     > +                                      (div == 1) ? 0x0 : 0x1)
     > +#define RPM_FROM_REG(reg)            (((reg) >> 4) ? \
     > +                                      ((32768 * 60) / ((reg) >> 4)) : \
     > +                                      FAN_RPM_MAX)
     > +#define RPM_TO_REG(rpm)                      ((rpm) ? \
     > +                                      ((32768 * 60) / (rpm)) : \
     > +                                      FAN_COUNT_REG_MAX)
     > +
     > +#define NR_CHANNEL                   8
     > +#define NR_FAN_CHANNEL                       4
     > +
     > +/*
     > + * Client data (each client gets its own)
     > + */
     > +struct ctf2304_data {
     > +     struct i2c_client *client;
     > +     struct mutex update_lock;
     > +     char valid; /* zero until following fields are valid */
     > +     unsigned long last_updated; /* in jiffies */
     > +
     > +     /* register values */
     > +     u16 local_temp;
     > +     u16 remote_channel[NR_CHANNEL];
     > +     u16 tach[NR_FAN_CHANNEL];
     > +     u16 fan_config1;
     > +     u16 fan_config2;
     > +     u16 fan_rpm_ctrl;
     > +     u16 pwm[NR_FAN_CHANNEL];
     > +     u16 target_count[NR_FAN_CHANNEL];
     > +};
     > +
     > +static struct ctf2304_data *ctf2304_update_device(struct device *dev)
     > +{
     > +     struct ctf2304_data *data = dev_get_drvdata(dev);
     > +     struct i2c_client *client = data->client;
     > +     struct ctf2304_data *ret = data;
     > +     int i;
     > +     int rv;
     > +
     > +     mutex_lock(&data->update_lock);
     > +
     > +     if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
     > +             rv = i2c_smbus_read_word_swapped(client,
     > +                             CTF2304_REG_LOCAL_TEMP);
     > +             if (rv < 0)
     > +                     goto abort;
     > +             data->local_temp = rv;
     > +
     > +             for (i = 0; i < NR_CHANNEL; i++) {
     > +                     rv = i2c_smbus_read_word_swapped(client,
     > +                                     CTF2304_REG_REMOTE_CHANNEL(i));
     > +                     if (rv < 0)
     > +                             goto abort;
     > +                     data->remote_channel[i] = rv;
     > +             }
     > +
     > +             rv = i2c_smbus_read_word_swapped(client,
     > +                             CTF2304_REG_FAN_CONFIG1);
     > +             if (rv < 0)
     > +                     goto abort;
     > +             data->fan_config1 = rv;
     > +             rv = i2c_smbus_read_word_swapped(client,
     > +                             CTF2304_REG_FAN_CONFIG2);
     > +             if (rv < 0)
     > +                     goto abort;
     > +             data->fan_config2 = rv;
     > +             rv = i2c_smbus_read_word_swapped(client,
     > +                             CTF2304_REG_FAN_RPM_CTRL);
     > +             if (rv < 0)
     > +                     goto abort;
     > +             data->fan_rpm_ctrl = rv;
     > +
     > +             for (i = 0; i < NR_FAN_CHANNEL; i++) {
     > +                     rv = i2c_smbus_read_word_swapped(client,
     > +                                     CTF2304_REG_TACH_COUNT(i));
     > +                     if (rv < 0)
     > +                             goto abort;
     > +                     data->tach[i] = rv;
     > +                     rv = i2c_smbus_read_word_swapped(client,
     > +                                     CTF2304_REG_PWMOUT(i));
     > +                     if (rv < 0)
     > +                             goto abort;
     > +                     data->pwm[i] = rv;
     > +                     rv = i2c_smbus_read_word_swapped(client,
     > +                                     CTF2304_REG_TARGET_COUNT(i));
     > +                     if (rv < 0)
     > +                             goto abort;
     > +                     data->target_count[i] = rv;
     > +             }
     > +
     > +             data->last_updated = jiffies;
     > +             data->valid = true;
     > +     }
     > +     goto done;
     > +
     > +abort:
     > +     data->valid = false;
     > +     ret = ERR_PTR(rv);
     > +
     > +done:
     > +     mutex_unlock(&data->update_lock);
     > +
     > +     return data;
     > +}
     > +
     > +static int ctf2304_read_temp(struct device *dev, u32 attr, int channel,
     > +                          long *val)
     > +{
     > +     struct ctf2304_data *data = ctf2304_update_device(dev);
     > +     u16 reg;
     > +
     > +     switch (attr) {
     > +     case hwmon_temp_input:
     > +             if (channel == 0)
     > +                     reg = data->local_temp;
     > +             else
     > +                     reg = data->remote_channel[channel-1];
     > +             *val = TEMP_FROM_REG(reg, (data->fan_config1
     > +                                        & CTF2304_FAN_CFG1_TRANGE));
     > +             return 0;
     > +     default:
     > +             return -EOPNOTSUPP;
     > +     }
     > +}
     > +
     > +static int get_full_scale(u16 config)
     > +{
     > +     int full_scale;
     > +     u8 bits;
     > +
     > +     bits = (config >> CTF2304_FAN_CFG1_MODE_SHIFT)
     > +            & CTF2304_FAN_CFG1_MODE_MASK;
     > +
     > +     if (bits == 0x0)
     > +             full_scale = 2560;
     > +     else if (bits == 0x1)
     > +             full_scale = CTF2304_VCC;
     > +     else if (bits == 0x2)
     > +             full_scale = 4096;
     > +     else if (bits == 0x3)
     > +             full_scale = 2048;
     > +     else if (bits == 0x4)
     > +             full_scale = 1024;
     > +     else if (bits == 0x5)
     > +             full_scale = 512;
     > +     else
     > +             full_scale = 256;
     > +
     > +     return full_scale;
     > +}
     > +
     > +static int ctf2304_read_in(struct device *dev, u32 attr, int channel,
     > +                        long *val)
     > +{
     > +     struct ctf2304_data *data = ctf2304_update_device(dev);
     > +
     > +     switch (attr) {
     > +     case hwmon_temp_input:
     > +             *val = VOLT_FROM_REG(data->remote_channel[channel],
     > +                                  get_full_scale(data->fan_config1));
     > +             return 0;
     > +     default:
     > +             return -EOPNOTSUPP;
     > +     }
     > +}
     > +
     > +static int ctf2304_read_fan(struct device *dev, u32 attr, int channel,
     > +                         long *val)
     > +{
     > +     struct ctf2304_data *data = ctf2304_update_device(dev);
     > +     u8 bits;
     > +
     > +     if (IS_ERR(data))
     > +             return PTR_ERR(data);
     > +
     > +     switch (attr) {
     > +     case hwmon_fan_input:
     > +             if (data->tach[channel] == FAN_COUNT_REG_MAX)
     > +                     *val = 0;
     > +             else
     > +                     *val = RPM_FROM_REG(data->tach[channel]);
     > +             return 0;
     > +     case hwmon_fan_target:
     > +             *val = RPM_FROM_REG(data->target_count[channel]);
     > +             return 0;
     > +     case hwmon_fan_div:
     > +             bits = (data->fan_rpm_ctrl & CTF2304_FAN_DIV_MASK(channel))
     > +                    >> CTF2304_FAN_DIV_SHIFT(channel);
     > +             *val = DIV_FROM_REG(bits);
     > +             return 0;
     > +     default:
     > +             return -EOPNOTSUPP;
     > +     }
     > +}
     > +
     > +static int ctf2304_write_fan(struct device *dev, u32 attr, int channel,
     > +                          long val)
     > +{
     > +     struct ctf2304_data *data = dev_get_drvdata(dev);
     > +     struct i2c_client *client = data->client;
     > +     int target_count;
     > +     int err = 0;
     > +
     > +     mutex_lock(&data->update_lock);
     > +
     > +     switch (attr) {
     > +     case hwmon_fan_target:
     > +             val = clamp_val(val, FAN_RPM_MIN, FAN_RPM_MAX);
     > +             target_count = RPM_TO_REG(val);
     > +             target_count = clamp_val(target_count, 0x1, 0xFFF);
     > +             data->target_count[channel] = target_count << 4;
     > +             err = i2c_smbus_write_word_swapped(client,
     > +                             CTF2304_REG_TARGET_COUNT(channel),
     > +                             data->target_count[channel]);
     > +             break;
     > +     case hwmon_fan_div:
     > +             data->fan_rpm_ctrl = (data->fan_rpm_ctrl
     > +                                   & ~CTF2304_FAN_DIV_MASK(channel))
     > +                                  | (DIV_TO_REG(val)
     > +                                     << CTF2304_FAN_DIV_SHIFT(channel));
     > +             err = i2c_smbus_write_word_swapped(client,
     > +                             CTF2304_REG_FAN_RPM_CTRL,
     > +                             data->fan_rpm_ctrl);
     > +             break;
     > +     default:
     > +             err = -EOPNOTSUPP;
     > +             break;
     > +     }
     > +
     > +     mutex_unlock(&data->update_lock);
     > +
     > +     return err;
     > +}
     > +
     > +static int ctf2304_read_pwm(struct device *dev, u32 attr, int channel,
     > +                         long *val)
     > +{
     > +     struct ctf2304_data *data = ctf2304_update_device(dev);
     > +     u8 bits;
     > +
     > +     if (IS_ERR(data))
     > +             return PTR_ERR(data);
     > +
     > +     switch (attr) {
     > +     case hwmon_pwm_input:
     > +             *val = data->pwm[channel] >> 8;
     > +             return 0;
     > +     case hwmon_pwm_enable:
     > +             bits = (data->fan_config2
     > +                     & CTF2304_FAN_CFG2_MODE_MASK(channel))
     > +                    >> CTF2304_FAN_CFG2_MODE_SHIFT(channel);
     > +             if (bits == CTF2304_FAN_CFG2_RPM_MODE)
     > +                     *val = 2;
     > +             else if (bits == CTF2304_FAN_CFG2_DCY_MODE)
     > +                     *val = 1;
     > +             else
     > +                     *val = 0;
     > +             return 0;
     > +     default:
     > +             return -EOPNOTSUPP;
     > +     }
     > +}
     > +
     > +static int ctf2304_write_pwm(struct device *dev, u32 attr, int channel,
     > +                          long val)
     > +{
     > +     struct ctf2304_data *data = dev_get_drvdata(dev);
     > +     struct i2c_client *client = data->client;
     > +     int err = 0;
     > +
     > +     mutex_lock(&data->update_lock);
     > +
     > +     switch (attr) {
     > +     case hwmon_pwm_input:
     > +             if (val < 0 || val > 255) {
     > +                     err = -EINVAL;
     > +                     break;
     > +             }
     > +             data->pwm[channel] = (data->pwm[channel] & 0xFF) | (val << 8);
     > +             err = i2c_smbus_write_word_swapped(client,
     > +                                                CTF2304_REG_PWMOUT(channel),
     > +                                                data->pwm[channel]);
     > +             break;
     > +     case hwmon_pwm_enable:
     > +             if (val == 0) {
     > +                     data->fan_config2 = (data->fan_config2
     > +                                          & ~CTF2304_FAN_CFG2_MODE_MASK(channel))
     > +                                         | (CTF2304_FAN_CFG2_TEMP_MODE
     > +                                            << CTF2304_FAN_CFG2_MODE_SHIFT(channel));
     > +             } else if (val == 1) {
     > +                     data->fan_config2 = (data->fan_config2
     > +                                          & ~CTF2304_FAN_CFG2_MODE_MASK(channel))
     > +                                         | (CTF2304_FAN_CFG2_DCY_MODE
     > +                                            << CTF2304_FAN_CFG2_MODE_SHIFT(channel));
     > +             } else if (val == 2) {
     > +                     data->fan_config2 = (data->fan_config2
     > +                                          & ~CTF2304_FAN_CFG2_MODE_MASK(channel))
     > +                                         | (CTF2304_FAN_CFG2_RPM_MODE
     > +                                            << CTF2304_FAN_CFG2_MODE_SHIFT(channel));
     > +             } else {
     > +                     err = -EINVAL;
     > +                     break;
     > +             }
     > +             err = i2c_smbus_write_word_swapped(client,
     > +                                                CTF2304_REG_FAN_CONFIG2,
     > +                                                data->fan_config2);
     > +             break;
     > +     default:
     > +             err = -EOPNOTSUPP;
     > +             break;
     > +     }
     > +
     > +     mutex_unlock(&data->update_lock);
     > +
     > +     return err;
     > +}
     > +
     > +static int ctf2304_read(struct device *dev, enum hwmon_sensor_types type,
     > +                     u32 attr, int channel, long *val)
     > +{
     > +     switch (type) {
     > +     case hwmon_temp:
     > +             return ctf2304_read_temp(dev, attr, channel, val);
     > +     case hwmon_in:
     > +             return ctf2304_read_in(dev, attr, channel, val);
     > +     case hwmon_fan:
     > +             return ctf2304_read_fan(dev, attr, channel, val);
     > +     case hwmon_pwm:
     > +             return ctf2304_read_pwm(dev, attr, channel, val);
     > +     default:
     > +             return -EOPNOTSUPP;
     > +     }
     > +}
     > +
     > +static int ctf2304_write(struct device *dev, enum hwmon_sensor_types type,
     > +                      u32 attr, int channel, long val)
     > +{
     > +     switch (type) {
     > +     case hwmon_fan:
     > +             return ctf2304_write_fan(dev, attr, channel, val);
     > +     case hwmon_pwm:
     > +             return ctf2304_write_pwm(dev, attr, channel, val);
     > +     default:
     > +             return -EOPNOTSUPP;
     > +     }
     > +}
     > +
     > +static umode_t ctf2304_is_visible(const void *data,
     > +                               enum hwmon_sensor_types type,
     > +                               u32 attr, int channel)
     > +{
     > +     switch (type) {
     > +     case hwmon_temp:
     > +     case hwmon_in:
     > +             return 0444;
     > +     case hwmon_fan:
     > +             switch (attr) {
     > +             case hwmon_fan_input:
     > +                     return 0444;
     > +             case hwmon_fan_target:
     > +             case hwmon_fan_div:
     > +                     return 0644;
     > +             default:
     > +                     break;
     > +             }
     > +             break;
     > +     case hwmon_pwm:
     > +             return 0644;
     > +     default:
     > +             break;
     > +     }
     > +
     > +     return 0;
     > +}
     > +
     > +static const struct hwmon_channel_info *ctf2304_info[] = {
     > +     HWMON_CHANNEL_INFO(temp,
     > +                        HWMON_T_INPUT,
     > +                        HWMON_T_INPUT,
     > +                        HWMON_T_INPUT,
     > +                        HWMON_T_INPUT,
     > +                        HWMON_T_INPUT,
     > +                        HWMON_T_INPUT,
     > +                        HWMON_T_INPUT,
     > +                        HWMON_T_INPUT,
     > +                        HWMON_T_INPUT),
     > +     HWMON_CHANNEL_INFO(in,
     > +                        HWMON_I_INPUT,
     > +                        HWMON_I_INPUT,
     > +                        HWMON_I_INPUT,
     > +                        HWMON_I_INPUT,
     > +                        HWMON_I_INPUT,
     > +                        HWMON_I_INPUT,
     > +                        HWMON_I_INPUT,
     > +                        HWMON_I_INPUT),
     > +     HWMON_CHANNEL_INFO(fan,
     > +                        HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_DIV,
     > +                        HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_DIV,
     > +                        HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_DIV,
     > +                        HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_DIV),
     > +     HWMON_CHANNEL_INFO(pwm,
     > +                        HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
     > +                        HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
     > +                        HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
     > +                        HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
     > +     NULL
     > +};
     > +
     > +static const struct hwmon_ops ctf2304_hwmon_ops = {
     > +     .is_visible = ctf2304_is_visible,
     > +     .read = ctf2304_read,
     > +     .write = ctf2304_write,
     > +};
     > +
     > +static const struct hwmon_chip_info ctf2304_chip_info = {
     > +     .ops = &ctf2304_hwmon_ops,
     > +     .info = ctf2304_info,
     > +};
     > +
     > +static int ctf2304_probe(struct i2c_client *client)
     > +{
     > +     struct i2c_adapter *adapter = client->adapter;
     > +     struct device *dev = &client->dev;
     > +     struct ctf2304_data *data;
     > +     struct device *hwmon_dev;
     > +
     > +     if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
     > +             return -ENODEV;
     > +
     > +     data = devm_kzalloc(dev, sizeof(struct ctf2304_data), GFP_KERNEL);
     > +     if (!data)
     > +             return -ENOMEM;
     > +
     > +     data->client = client;
     > +     mutex_init(&data->update_lock);
     > +
     > +     hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
     > +                                                      data,
     > +                                                      &ctf2304_chip_info,
     > +                                                      NULL);
     > +
     > +     return PTR_ERR_OR_ZERO(hwmon_dev);
     > +}
     > +
     > +static const struct i2c_device_id ctf2304_id[] = {
     > +     { "ctf2304", 0 },
     > +     { }
     > +};
     > +MODULE_DEVICE_TABLE(i2c, ctf2304_id);
     > +
     > +static struct i2c_driver ctf2304_driver = {
     > +     .class          = I2C_CLASS_HWMON,
     > +     .driver = {
     > +             .name   = "ctf2304",
     > +     },
     > +     .probe_new      = ctf2304_probe,
     > +     .id_table       = ctf2304_id,
     > +};
     > +
     > +module_i2c_driver(ctf2304_driver);
     > +
     > +MODULE_AUTHOR("Il Han <corone.il.han@xxxxxxxxx <mailto:corone.il.han@xxxxxxxxx>>");
     > +MODULE_DESCRIPTION("CTF2304 sensor driver");
     > +MODULE_LICENSE("GPL");
     > --
     > 2.26.3
     >





[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux