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 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 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 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 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 87*a748d30cSCosmin Tanislav return adt7x10_probe(&client->dev, client->name, client->irq, regmap); 88983b97beSHartmut Knaack } 89983b97beSHartmut Knaack 9051c2a487SLars-Peter Clausen static int adt7410_i2c_remove(struct i2c_client *client) 91983b97beSHartmut Knaack { 92beee7890SUwe Kleine-König adt7x10_remove(&client->dev, client->irq); 93beee7890SUwe Kleine-König return 0; 94983b97beSHartmut Knaack } 95983b97beSHartmut Knaack 96983b97beSHartmut Knaack static const struct i2c_device_id adt7410_ids[] = { 9751c2a487SLars-Peter Clausen { "adt7410", 0 }, 9851c2a487SLars-Peter Clausen { "adt7420", 0 }, 9951c2a487SLars-Peter Clausen {} 100983b97beSHartmut Knaack }; 101983b97beSHartmut Knaack MODULE_DEVICE_TABLE(i2c, adt7410_ids); 102983b97beSHartmut Knaack 103983b97beSHartmut Knaack static struct i2c_driver adt7410_driver = { 104983b97beSHartmut Knaack .class = I2C_CLASS_HWMON, 105983b97beSHartmut Knaack .driver = { 106983b97beSHartmut Knaack .name = "adt7410", 10751c2a487SLars-Peter Clausen .pm = ADT7X10_DEV_PM_OPS, 108983b97beSHartmut Knaack }, 10967487038SStephen Kitt .probe_new = adt7410_i2c_probe, 11051c2a487SLars-Peter Clausen .remove = adt7410_i2c_remove, 111983b97beSHartmut Knaack .id_table = adt7410_ids, 11254be068dSLars-Peter Clausen .address_list = I2C_ADDRS(0x48, 0x49, 0x4a, 0x4b), 113983b97beSHartmut Knaack }; 114983b97beSHartmut Knaack module_i2c_driver(adt7410_driver); 115983b97beSHartmut Knaack 11651c2a487SLars-Peter Clausen MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 11751c2a487SLars-Peter Clausen MODULE_DESCRIPTION("ADT7410/AD7420 driver"); 118983b97beSHartmut Knaack MODULE_LICENSE("GPL"); 119