180503b23SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2983b97beSHartmut Knaack /*
351c2a487SLars-Peter Clausen * ADT7410/ADT7420 digital temperature sensor driver
4983b97beSHartmut Knaack *
551c2a487SLars-Peter Clausen * Copyright 2012-2013 Analog Devices Inc.
651c2a487SLars-Peter Clausen * Author: Lars-Peter Clausen <lars@metafoo.de>
7983b97beSHartmut Knaack */
8983b97beSHartmut Knaack
9983b97beSHartmut Knaack #include <linux/module.h>
10983b97beSHartmut Knaack #include <linux/init.h>
11983b97beSHartmut Knaack #include <linux/i2c.h>
12f5320701SGuenter Roeck #include <linux/regmap.h>
13983b97beSHartmut Knaack
1451c2a487SLars-Peter Clausen #include "adt7x10.h"
15983b97beSHartmut Knaack
adt7410_regmap_is_volatile(struct device * dev,unsigned int reg)16f5320701SGuenter Roeck static bool adt7410_regmap_is_volatile(struct device *dev, unsigned int reg)
1751c2a487SLars-Peter Clausen {
18f5320701SGuenter Roeck switch (reg) {
19f5320701SGuenter Roeck case ADT7X10_TEMPERATURE:
20f5320701SGuenter Roeck case ADT7X10_STATUS:
21f5320701SGuenter Roeck return true;
22f5320701SGuenter Roeck default:
23f5320701SGuenter Roeck return false;
24f5320701SGuenter Roeck }
2551c2a487SLars-Peter Clausen }
26983b97beSHartmut Knaack
adt7410_reg_read(void * context,unsigned int reg,unsigned int * val)27f5320701SGuenter Roeck static int adt7410_reg_read(void *context, unsigned int reg, unsigned int *val)
2851c2a487SLars-Peter Clausen {
29f5320701SGuenter Roeck struct i2c_client *client = context;
30f5320701SGuenter Roeck int regval;
31f5320701SGuenter Roeck
32f5320701SGuenter Roeck switch (reg) {
33f5320701SGuenter Roeck case ADT7X10_TEMPERATURE:
34f5320701SGuenter Roeck case ADT7X10_T_ALARM_HIGH:
35f5320701SGuenter Roeck case ADT7X10_T_ALARM_LOW:
36f5320701SGuenter Roeck case ADT7X10_T_CRIT:
37f5320701SGuenter Roeck regval = i2c_smbus_read_word_swapped(client, reg);
38f5320701SGuenter Roeck break;
39f5320701SGuenter Roeck default:
40f5320701SGuenter Roeck regval = i2c_smbus_read_byte_data(client, reg);
41f5320701SGuenter Roeck break;
42f5320701SGuenter Roeck }
43f5320701SGuenter Roeck if (regval < 0)
44f5320701SGuenter Roeck return regval;
45f5320701SGuenter Roeck *val = regval;
46f5320701SGuenter Roeck return 0;
4751c2a487SLars-Peter Clausen }
48983b97beSHartmut Knaack
adt7410_reg_write(void * context,unsigned int reg,unsigned int val)49f5320701SGuenter Roeck static int adt7410_reg_write(void *context, unsigned int reg, unsigned int val)
5051c2a487SLars-Peter Clausen {
51f5320701SGuenter Roeck struct i2c_client *client = context;
52f5320701SGuenter Roeck int ret;
53f5320701SGuenter Roeck
54f5320701SGuenter Roeck switch (reg) {
55f5320701SGuenter Roeck case ADT7X10_TEMPERATURE:
56f5320701SGuenter Roeck case ADT7X10_T_ALARM_HIGH:
57f5320701SGuenter Roeck case ADT7X10_T_ALARM_LOW:
58f5320701SGuenter Roeck case ADT7X10_T_CRIT:
59f5320701SGuenter Roeck ret = i2c_smbus_write_word_swapped(client, reg, val);
60f5320701SGuenter Roeck break;
61f5320701SGuenter Roeck default:
62f5320701SGuenter Roeck ret = i2c_smbus_write_byte_data(client, reg, val);
63f5320701SGuenter Roeck break;
64f5320701SGuenter Roeck }
65f5320701SGuenter Roeck return ret;
6651c2a487SLars-Peter Clausen }
67983b97beSHartmut Knaack
68f5320701SGuenter Roeck static const struct regmap_config adt7410_regmap_config = {
69f5320701SGuenter Roeck .reg_bits = 8,
70f5320701SGuenter Roeck .val_bits = 16,
71f5320701SGuenter Roeck .max_register = ADT7X10_ID,
72f5320701SGuenter Roeck .cache_type = REGCACHE_RBTREE,
73f5320701SGuenter Roeck .volatile_reg = adt7410_regmap_is_volatile,
74f5320701SGuenter Roeck .reg_read = adt7410_reg_read,
75f5320701SGuenter Roeck .reg_write = adt7410_reg_write,
76983b97beSHartmut Knaack };
77983b97beSHartmut Knaack
adt7410_i2c_probe(struct i2c_client * client)7867487038SStephen Kitt static int adt7410_i2c_probe(struct i2c_client *client)
79983b97beSHartmut Knaack {
80f5320701SGuenter Roeck struct regmap *regmap;
81983b97beSHartmut Knaack
82f5320701SGuenter Roeck regmap = devm_regmap_init(&client->dev, NULL, client,
83f5320701SGuenter Roeck &adt7410_regmap_config);
84f5320701SGuenter Roeck if (IS_ERR(regmap))
85f5320701SGuenter Roeck return PTR_ERR(regmap);
86f5320701SGuenter Roeck
87a748d30cSCosmin Tanislav return adt7x10_probe(&client->dev, client->name, client->irq, regmap);
88983b97beSHartmut Knaack }
89983b97beSHartmut Knaack
90983b97beSHartmut Knaack static const struct i2c_device_id adt7410_ids[] = {
9151c2a487SLars-Peter Clausen { "adt7410", 0 },
9251c2a487SLars-Peter Clausen { "adt7420", 0 },
9351c2a487SLars-Peter Clausen {}
94983b97beSHartmut Knaack };
95983b97beSHartmut Knaack MODULE_DEVICE_TABLE(i2c, adt7410_ids);
96983b97beSHartmut Knaack
97983b97beSHartmut Knaack static struct i2c_driver adt7410_driver = {
98983b97beSHartmut Knaack .class = I2C_CLASS_HWMON,
99983b97beSHartmut Knaack .driver = {
100983b97beSHartmut Knaack .name = "adt7410",
10129805956SJonathan Cameron .pm = pm_sleep_ptr(&adt7x10_dev_pm_ops),
102983b97beSHartmut Knaack },
103*1975d167SUwe Kleine-König .probe = adt7410_i2c_probe,
104983b97beSHartmut Knaack .id_table = adt7410_ids,
10554be068dSLars-Peter Clausen .address_list = I2C_ADDRS(0x48, 0x49, 0x4a, 0x4b),
106983b97beSHartmut Knaack };
107983b97beSHartmut Knaack module_i2c_driver(adt7410_driver);
108983b97beSHartmut Knaack
10951c2a487SLars-Peter Clausen MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
11051c2a487SLars-Peter Clausen MODULE_DESCRIPTION("ADT7410/AD7420 driver");
111983b97beSHartmut Knaack MODULE_LICENSE("GPL");
112