diff options
Diffstat (limited to 'drivers/hwmon')
| -rw-r--r-- | drivers/hwmon/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
| -rw-r--r-- | drivers/hwmon/adt7410.c | 8 | ||||
| -rw-r--r-- | drivers/hwmon/aht10.c | 7 | ||||
| -rw-r--r-- | drivers/hwmon/ds1621.c | 10 | ||||
| -rw-r--r-- | drivers/hwmon/emc2305.c | 71 | ||||
| -rw-r--r-- | drivers/hwmon/pwm-fan.c | 56 | ||||
| -rw-r--r-- | drivers/hwmon/rp1-adc.c | 305 | ||||
| -rw-r--r-- | drivers/hwmon/sht3x.c | 16 |
9 files changed, 465 insertions, 16 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 2760feb9f83b..189194219eec 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -2660,6 +2660,13 @@ config SENSORS_INTEL_M10_BMC_HWMON sensors monitor various telemetry data of different components on the card, e.g. board temperature, FPGA core temperature/voltage/current. +config SENSORS_RP1_ADC + tristate "RP1 ADC and temperature sensor driver" + depends on MFD_RP1 + help + Say yes here to enable support for the voltage and temperature + sensors of the Raspberry Pi RP1 peripheral chip. + if ACPI comment "ACPI drivers" diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 73b2abdcc6dd..7f4b2186c74b 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -198,6 +198,7 @@ obj-$(CONFIG_SENSORS_PT5161L) += pt5161l.o obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o obj-$(CONFIG_SENSORS_QNAP_MCU_HWMON) += qnap-mcu-hwmon.o obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o +obj-$(CONFIG_SENSORS_RP1_ADC) += rp1-adc.o obj-$(CONFIG_SENSORS_SA67MCU) += sa67mcu-hwmon.o obj-$(CONFIG_SENSORS_SBTSI) += sbtsi_temp.o obj-$(CONFIG_SENSORS_SBRMI) += sbrmi.o diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c index 3bf0e0a0882c..1b52d90815ac 100644 --- a/drivers/hwmon/adt7410.c +++ b/drivers/hwmon/adt7410.c @@ -94,9 +94,17 @@ static const struct i2c_device_id adt7410_ids[] = { }; MODULE_DEVICE_TABLE(i2c, adt7410_ids); +static const struct of_device_id adt7410_of_ids[] = { + { .compatible = "adi,adt7410" }, + { .compatible = "adi,adt7420" }, + {} +}; +MODULE_DEVICE_TABLE(of, adt7410_of_ids); + static struct i2c_driver adt7410_driver = { .driver = { .name = "adt7410", + .of_match_table = adt7410_of_ids, .pm = pm_sleep_ptr(&adt7x10_dev_pm_ops), }, .probe = adt7410_i2c_probe, diff --git a/drivers/hwmon/aht10.c b/drivers/hwmon/aht10.c index d1c55e2eb479..ada23a3ce2ff 100644 --- a/drivers/hwmon/aht10.c +++ b/drivers/hwmon/aht10.c @@ -57,6 +57,12 @@ static const struct i2c_device_id aht10_id[] = { }; MODULE_DEVICE_TABLE(i2c, aht10_id); +static const struct of_device_id aht10_of_id[] = { + { .compatible = "aosong,aht10", }, + { } +}; +MODULE_DEVICE_TABLE(of, aht10_of_id); + /** * struct aht10_data - All the data required to operate an AHT10/AHT20 chip * @client: the i2c client associated with the AHT10/AHT20 @@ -380,6 +386,7 @@ static int aht10_probe(struct i2c_client *client) static struct i2c_driver aht10_driver = { .driver = { .name = "aht10", + .of_match_table = aht10_of_id, }, .probe = aht10_probe, .id_table = aht10_id, diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 42ec34cb8a5f..30d2a771054f 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -376,6 +376,16 @@ static const struct i2c_device_id ds1621_id[] = { }; MODULE_DEVICE_TABLE(i2c, ds1621_id); +static const struct of_device_id ds1621_of_ids[] = { + { .compatible = "dallas,ds1621", }, + { .compatible = "dallas,ds1625", }, + { .compatible = "dallas,ds1631", }, + { .compatible = "dallas,ds1721", }, + { .compatible = "dallas,ds1731", }, + { } +}; +MODULE_DEVICE_TABLE(of, ds1621_of_ids); + /* This is the driver that will be inserted */ static struct i2c_driver ds1621_driver = { .driver = { diff --git a/drivers/hwmon/emc2305.c b/drivers/hwmon/emc2305.c index 60809289f816..ccfed1be775a 100644 --- a/drivers/hwmon/emc2305.c +++ b/drivers/hwmon/emc2305.c @@ -15,12 +15,13 @@ #include <linux/of_device.h> #include <linux/util_macros.h> +#define EMC2305_REG_FAN_STATUS 0x24 +#define EMC2305_REG_FAN_STALL_STATUS 0x25 #define EMC2305_REG_DRIVE_FAIL_STATUS 0x27 #define EMC2305_REG_VENDOR 0xfe #define EMC2305_FAN_MAX 0xff #define EMC2305_FAN_MIN 0x00 #define EMC2305_FAN_MAX_STATE 10 -#define EMC2305_DEVICE 0x34 #define EMC2305_VENDOR 0x5d #define EMC2305_REG_PRODUCT_ID 0xfd #define EMC2305_TACH_REGS_UNUSE_BITS 3 @@ -45,6 +46,7 @@ #define EMC2305_RPM_FACTOR 3932160 #define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * (n)) +#define EMC2305_REG_FAN_CFG(n) (0x32 + 0x10 * (n)) #define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * (n)) #define EMC2305_REG_FAN_TACH(n) (0x3e + 0x10 * (n)) @@ -67,6 +69,15 @@ static const struct i2c_device_id emc2305_ids[] = { }; MODULE_DEVICE_TABLE(i2c, emc2305_ids); +static const struct of_device_id emc2305_dt_ids[] = { + { .compatible = "microchip,emc2305" }, + { .compatible = "microchip,emc2303" }, + { .compatible = "microchip,emc2302" }, + { .compatible = "microchip,emc2301" }, + { } +}; +MODULE_DEVICE_TABLE(of, emc2305_dt_ids); + /** * struct emc2305_cdev_data - device-specific cooling device state * @cdev: cooling device @@ -117,6 +128,7 @@ struct emc2305_data { u8 pwm_polarity_mask; bool pwm_separate; u8 pwm_min[EMC2305_PWM_MAX]; + u8 pwm_max; u16 pwm_freq[EMC2305_PWM_MAX]; struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX]; }; @@ -288,7 +300,7 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel) struct i2c_client *client = data->client; int ret; - if (val < data->pwm_min[channel] || val > EMC2305_FAN_MAX) + if (val < data->pwm_min[channel] || val > data->pwm_max) return -EINVAL; ret = i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_DRIVE(channel), val); @@ -299,6 +311,49 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel) return 0; } +static int emc2305_get_tz_of(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct emc2305_data *data = dev_get_drvdata(dev); + int ret = 0; + u8 val; + int i; + + /* OF parameters are optional - overwrite default setting + * if some of them are provided. + */ + + ret = of_property_read_u8(np, "emc2305,cooling-levels", &val); + if (!ret) + data->max_state = val; + else if (ret != -EINVAL) + return ret; + + ret = of_property_read_u8(np, "emc2305,pwm-max", &val); + if (!ret) + data->pwm_max = val; + else if (ret != -EINVAL) + return ret; + + ret = of_property_read_u8(np, "emc2305,pwm-min", &val); + if (!ret) + for (i = 0; i < EMC2305_PWM_MAX; i++) + data->pwm_min[i] = val; + else if (ret != -EINVAL) + return ret; + + /* Not defined or 0 means one thermal zone over all cooling devices. + * Otherwise - separated thermal zones for each PWM channel. + */ + ret = of_property_read_u8(np, "emc2305,pwm-channel", &val); + if (!ret) + data->pwm_separate = (val != 0); + else if (ret != -EINVAL) + return ret; + + return 0; +} + static int emc2305_set_single_tz(struct device *dev, struct device_node *fan_node, int idx) { struct emc2305_data *data = dev_get_drvdata(dev); @@ -672,6 +727,12 @@ static int emc2305_probe(struct i2c_client *client) data->pwm_separate = false; for (i = 0; i < EMC2305_PWM_MAX; i++) data->pwm_min[i] = EMC2305_FAN_MIN; + data->pwm_max = EMC2305_FAN_MAX; + if (dev->of_node) { + ret = emc2305_get_tz_of(dev); + if (ret < 0) + return ret; + } } data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "emc2305", data, @@ -713,6 +774,12 @@ static int emc2305_probe(struct i2c_client *client) return ret; } + /* Acknowledge any existing faults. Stops the device responding on the + * SMBus alert address. + */ + i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STALL_STATUS); + i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STATUS); + return 0; } diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 37269db2de84..c1ac5ae92a2a 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/platform_device.h> +#include <linux/of_address.h> #include <linux/property.h> #include <linux/pwm.h> #include <linux/regulator/consumer.h> @@ -53,6 +54,9 @@ struct pwm_fan_ctx { ktime_t sample_start; struct timer_list rpm_timer; + void __iomem *rpm_regbase; + unsigned int rpm_offset; + unsigned int pwm_value; unsigned int pwm_fan_state; unsigned int pwm_fan_max_state; @@ -67,6 +71,10 @@ struct pwm_fan_ctx { u8 pwm_shutdown; }; +static const u32 rpm_reg_channel_config[] = { + HWMON_F_INPUT, 0 +}; + /* This handler assumes self resetting edge triggered interrupt. */ static irqreturn_t pulse_handler(int irq, void *dev_id) { @@ -355,7 +363,10 @@ static int pwm_fan_read(struct device *dev, enum hwmon_sensor_types type, } return -EOPNOTSUPP; case hwmon_fan: - *val = ctx->tachs[channel].rpm; + if (ctx->rpm_regbase) + *val = (long)readl(ctx->rpm_regbase + ctx->rpm_offset); + else + *val = ctx->tachs[channel].rpm; return 0; default: @@ -577,10 +588,23 @@ static int pwm_fan_probe(struct platform_device *pdev) return ret; ctx->tach_count = platform_irq_count(pdev); + if (ctx->tach_count == 0) { + struct device_node *rpm_node; + + rpm_node = of_parse_phandle(dev->of_node, "rpm-regmap", 0); + if (rpm_node) + ctx->rpm_regbase = of_iomap(rpm_node, 0); + } + if (ctx->tach_count < 0) return dev_err_probe(dev, ctx->tach_count, "Could not get number of fan tachometer inputs\n"); - dev_dbg(dev, "%d fan tachometer inputs\n", ctx->tach_count); + if (IS_ERR(ctx->rpm_regbase)) + return dev_err_probe(dev, PTR_ERR(ctx->rpm_regbase), + "Could not get rpm reg\n"); + + dev_dbg(dev, "%d fan tachometer inputs, %d rpm regmap\n", ctx->tach_count, + !!ctx->rpm_regbase); if (ctx->tach_count) { channel_count++; /* We also have a FAN channel. */ @@ -611,12 +635,24 @@ static int pwm_fan_probe(struct platform_device *pdev) device_property_read_u32_array(dev, "pulses-per-revolution", ctx->pulses_per_revolution, ctx->tach_count); + } else if (ctx->rpm_regbase) { + channel_count++; /* We also have a FAN channel. */ + ctx->fan_channel.type = hwmon_fan; + ctx->fan_channel.config = rpm_reg_channel_config; + + if (device_property_read_u32(dev, "rpm-offset", &ctx->rpm_offset)) { + dev_err(&pdev->dev, "unable to read 'rpm-offset'"); + ret = -EINVAL; + goto error; + } } channels = devm_kcalloc(dev, channel_count + 1, sizeof(struct hwmon_channel_info *), GFP_KERNEL); - if (!channels) - return -ENOMEM; + if (!channels) { + ret = -ENOMEM; + goto error; + } channels[0] = HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_ENABLE); @@ -653,6 +689,8 @@ static int pwm_fan_probe(struct platform_device *pdev) mod_timer(&ctx->rpm_timer, jiffies + HZ); channels[1] = &ctx->fan_channel; + } else if (ctx->rpm_regbase) { + channels[1] = &ctx->fan_channel; } ret = device_property_read_u32(dev, "fan-shutdown-percent", @@ -680,7 +718,8 @@ static int pwm_fan_probe(struct platform_device *pdev) ctx, &ctx->info, NULL); if (IS_ERR(hwmon)) { dev_err(dev, "Failed to register hwmon device\n"); - return PTR_ERR(hwmon); + ret = PTR_ERR(hwmon); + goto error; } ctx->pwm_fan_state = ctx->pwm_fan_max_state; @@ -692,12 +731,17 @@ static int pwm_fan_probe(struct platform_device *pdev) dev_err(dev, "Failed to register pwm-fan as cooling device: %d\n", ret); - return ret; + goto error; } ctx->cdev = cdev; } return 0; + +error: + if (ctx->rpm_regbase) + iounmap(ctx->rpm_regbase); + return ret; } static void pwm_fan_shutdown(struct platform_device *pdev) diff --git a/drivers/hwmon/rp1-adc.c b/drivers/hwmon/rp1-adc.c new file mode 100644 index 000000000000..3201a3cfa7a9 --- /dev/null +++ b/drivers/hwmon/rp1-adc.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for the RP1 ADC and temperature sensor + * Copyright (C) 2023 Raspberry Pi Ltd. + */ + +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> + +#define MODULE_NAME "rp1-adc" + +#define RP1_ADC_CS 0x00 +#define RP1_ADC_RESULT 0x04 +#define RP1_ADC_FCS 0x08 +#define RP1_ADC_FIFO 0x0c +#define RP1_ADC_DIV 0x10 + +#define RP1_ADC_INTR 0x14 +#define RP1_ADC_INTE 0x18 +#define RP1_ADC_INTF 0x1c +#define RP1_ADC_INTS 0x20 + +#define RP1_ADC_RWTYPE_SET 0x2000 +#define RP1_ADC_RWTYPE_CLR 0x3000 + +#define RP1_ADC_CS_RROBIN_MASK 0x1f +#define RP1_ADC_CS_RROBIN_SHIFT 16 +#define RP1_ADC_CS_AINSEL_MASK 0x7 +#define RP1_ADC_CS_AINSEL_SHIFT 12 +#define RP1_ADC_CS_ERR_STICKY 0x400 +#define RP1_ADC_CS_ERR 0x200 +#define RP1_ADC_CS_READY 0x100 +#define RP1_ADC_CS_START_MANY 0x8 +#define RP1_ADC_CS_START_ONCE 0x4 +#define RP1_ADC_CS_TS_EN 0x2 +#define RP1_ADC_CS_EN 0x1 + +#define RP1_ADC_FCS_THRESH_MASK 0xf +#define RP1_ADC_FCS_THRESH_SHIFT 24 +#define RP1_ADC_FCS_LEVEL_MASK 0xf +#define RP1_ADC_FCS_LEVEL_SHIFT 16 +#define RP1_ADC_FCS_OVER 0x800 +#define RP1_ADC_FCS_UNDER 0x400 +#define RP1_ADC_FCS_FULL 0x200 +#define RP1_ADC_FCS_EMPTY 0x100 +#define RP1_ADC_FCS_DREQ_EN 0x8 +#define RP1_ADC_FCS_ERR 0x4 +#define RP1_ADC_FCS_SHIFR 0x2 +#define RP1_ADC_FCS_EN 0x1 + +#define RP1_ADC_FIFO_ERR 0x8000 +#define RP1_ADC_FIFO_VAL_MASK 0xfff + +#define RP1_ADC_DIV_INT_MASK 0xffff +#define RP1_ADC_DIV_INT_SHIFT 8 +#define RP1_ADC_DIV_FRAC_MASK 0xff +#define RP1_ADC_DIV_FRAC_SHIFT 0 + +struct rp1_adc_data { + void __iomem *base; + spinlock_t lock; + struct device *hwmon_dev; + int vref_mv; +}; + +static int rp1_adc_ready_wait(struct rp1_adc_data *data) +{ + int retries = 10; + + while (retries && !(readl(data->base + RP1_ADC_CS) & RP1_ADC_CS_READY)) + retries--; + + return retries ? 0 : -EIO; +} + +static int rp1_adc_read(struct rp1_adc_data *data, + struct device_attribute *devattr, unsigned int *val) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int channel = attr->index; + int ret; + + spin_lock(&data->lock); + + writel(RP1_ADC_CS_AINSEL_MASK << RP1_ADC_CS_AINSEL_SHIFT, + data->base + RP1_ADC_RWTYPE_CLR + RP1_ADC_CS); + writel(channel << RP1_ADC_CS_AINSEL_SHIFT, + data->base + RP1_ADC_RWTYPE_SET + RP1_ADC_CS); + writel(RP1_ADC_CS_START_ONCE, + data->base + RP1_ADC_RWTYPE_SET + RP1_ADC_CS); + + ret = rp1_adc_ready_wait(data); + if (ret) + return ret; + + /* Asserted if the completed conversion had a convergence error */ + if (readl(data->base + RP1_ADC_CS) & RP1_ADC_CS_ERR) + return -EIO; + + *val = readl(data->base + RP1_ADC_RESULT); + + spin_unlock(&data->lock); + + return ret; +} + +static int rp1_adc_to_mv(struct rp1_adc_data *data, unsigned int val) +{ + return ((u64)data->vref_mv * val) / 0xfff; +} + +static ssize_t rp1_adc_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct rp1_adc_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret; + + ret = rp1_adc_read(data, devattr, &val); + if (ret) + return ret; + + return sprintf(buf, "%d\n", rp1_adc_to_mv(data, val)); +} + +static ssize_t rp1_adc_temp_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct rp1_adc_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret, mv, mc; + + writel(RP1_ADC_CS_TS_EN, + data->base + RP1_ADC_RWTYPE_SET + RP1_ADC_CS); + ret = rp1_adc_read(data, devattr, &val); + if (ret) + return ret; + + mv = rp1_adc_to_mv(data, val); + + /* T = 27 - (ADC_voltage - 0.706)/0.001721 */ + + mc = 27000 - DIV_ROUND_CLOSEST((mv - 706) * (s64)1000000, 1721); + + return sprintf(buf, "%d\n", mc); +} + +static ssize_t rp1_adc_raw_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct rp1_adc_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret = rp1_adc_read(data, devattr, &val); + + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t rp1_adc_temp_raw_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct rp1_adc_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret = rp1_adc_read(data, devattr, &val); + + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static SENSOR_DEVICE_ATTR_RO(in1_input, rp1_adc, 0); +static SENSOR_DEVICE_ATTR_RO(in2_input, rp1_adc, 1); +static SENSOR_DEVICE_ATTR_RO(in3_input, rp1_adc, 2); +static SENSOR_DEVICE_ATTR_RO(in4_input, rp1_adc, 3); +static SENSOR_DEVICE_ATTR_RO(temp1_input, rp1_adc_temp, 4); +static SENSOR_DEVICE_ATTR_RO(in1_raw, rp1_adc_raw, 0); +static SENSOR_DEVICE_ATTR_RO(in2_raw, rp1_adc_raw, 1); +static SENSOR_DEVICE_ATTR_RO(in3_raw, rp1_adc_raw, 2); +static SENSOR_DEVICE_ATTR_RO(in4_raw, rp1_adc_raw, 3); +static SENSOR_DEVICE_ATTR_RO(temp1_raw, rp1_adc_temp_raw, 4); + +static struct attribute *rp1_adc_attrs[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_in1_raw.dev_attr.attr, + &sensor_dev_attr_in2_raw.dev_attr.attr, + &sensor_dev_attr_in3_raw.dev_attr.attr, + &sensor_dev_attr_in4_raw.dev_attr.attr, + &sensor_dev_attr_temp1_raw.dev_attr.attr, + NULL +}; + +static umode_t rp1_adc_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + return 0444; +} + +static const struct attribute_group rp1_adc_group = { + .attrs = rp1_adc_attrs, + .is_visible = rp1_adc_is_visible, +}; +__ATTRIBUTE_GROUPS(rp1_adc); + +static int __init rp1_adc_probe(struct platform_device *pdev) +{ + struct rp1_adc_data *data; + struct regulator *reg; + struct clk *clk; + int vref_uv, ret; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + spin_lock_init(&data->lock); + + data->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(data->base)) + return PTR_ERR(data->base); + + platform_set_drvdata(pdev, data); + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) + return -ENODEV; + + clk_set_rate(clk, 50000000); + clk_prepare_enable(clk); + + reg = devm_regulator_get(&pdev->dev, "vref"); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + vref_uv = regulator_get_voltage(reg); + data->vref_mv = DIV_ROUND_CLOSEST(vref_uv, 1000); + + data->hwmon_dev = + devm_hwmon_device_register_with_groups(&pdev->dev, + "rp1_adc", + data, + rp1_adc_groups); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + dev_err(&pdev->dev, "hwmon_device_register failed with %d.\n", ret); + goto err_register; + } + + /* Disable interrupts */ + writel(0, data->base + RP1_ADC_INTE); + + /* Enable the block, clearing any sticky error */ + writel(RP1_ADC_CS_EN | RP1_ADC_CS_ERR_STICKY, data->base + RP1_ADC_CS); + + return 0; + +err_register: + sysfs_remove_group(&pdev->dev.kobj, &rp1_adc_group); + + return ret; +} + +static void rp1_adc_remove(struct platform_device *pdev) +{ + struct rp1_adc_data *data = platform_get_drvdata(pdev); + + hwmon_device_unregister(data->hwmon_dev); +} + +static const struct of_device_id rp1_adc_dt_ids[] = { + { .compatible = "raspberrypi,rp1-adc", }, + { } +}; +MODULE_DEVICE_TABLE(of, rp1_adc_dt_ids); + +static struct platform_driver rp1_adc_driver = { + .remove = rp1_adc_remove, + .driver = { + .name = MODULE_NAME, + .of_match_table = rp1_adc_dt_ids, + }, +}; + +module_platform_driver_probe(rp1_adc_driver, rp1_adc_probe); + +MODULE_DESCRIPTION("RP1 ADC driver"); +MODULE_AUTHOR("Phil Elwell <[email protected]>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c index f36c0229328f..e974d0800fe3 100644 --- a/drivers/hwmon/sht3x.c +++ b/drivers/hwmon/sht3x.c @@ -929,19 +929,19 @@ static int sht3x_probe(struct i2c_client *client) return 0; } -/* device ID table */ -static const struct i2c_device_id sht3x_ids[] = { - {"sht3x", sht3x}, - {"sts3x", sts3x}, +static const struct of_device_id sht3x_of_ids[] = { + { .compatible = "sensirion,sht3x" }, + { .compatible = "sensirion,sts3x" }, {} }; - -MODULE_DEVICE_TABLE(i2c, sht3x_ids); +MODULE_DEVICE_TABLE(of, sht3x_of_ids); static struct i2c_driver sht3x_i2c_driver = { - .driver.name = "sht3x", + .driver = { + .name = "sht3x", + .of_match_table = sht3x_of_ids, + }, .probe = sht3x_probe, - .id_table = sht3x_ids, }; module_i2c_driver(sht3x_i2c_driver); |
