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> 12*f5320701SGuenter Roeck #include <linux/regmap.h> 13983b97beSHartmut Knaack 1451c2a487SLars-Peter Clausen #include "adt7x10.h" 15983b97beSHartmut Knaack 16*f5320701SGuenter Roeck static bool adt7410_regmap_is_volatile(struct device *dev, unsigned int reg) 1751c2a487SLars-Peter Clausen { 18*f5320701SGuenter Roeck switch (reg) { 19*f5320701SGuenter Roeck case ADT7X10_TEMPERATURE: 20*f5320701SGuenter Roeck case ADT7X10_STATUS: 21*f5320701SGuenter Roeck return true; 22*f5320701SGuenter Roeck default: 23*f5320701SGuenter Roeck return false; 24*f5320701SGuenter Roeck } 2551c2a487SLars-Peter Clausen } 26983b97beSHartmut Knaack 27*f5320701SGuenter Roeck static int adt7410_reg_read(void *context, unsigned int reg, unsigned int *val) 2851c2a487SLars-Peter Clausen { 29*f5320701SGuenter Roeck struct i2c_client *client = context; 30*f5320701SGuenter Roeck int regval; 31*f5320701SGuenter Roeck 32*f5320701SGuenter Roeck switch (reg) { 33*f5320701SGuenter Roeck case ADT7X10_TEMPERATURE: 34*f5320701SGuenter Roeck case ADT7X10_T_ALARM_HIGH: 35*f5320701SGuenter Roeck case ADT7X10_T_ALARM_LOW: 36*f5320701SGuenter Roeck case ADT7X10_T_CRIT: 37*f5320701SGuenter Roeck regval = i2c_smbus_read_word_swapped(client, reg); 38*f5320701SGuenter Roeck break; 39*f5320701SGuenter Roeck default: 40*f5320701SGuenter Roeck regval = i2c_smbus_read_byte_data(client, reg); 41*f5320701SGuenter Roeck break; 42*f5320701SGuenter Roeck } 43*f5320701SGuenter Roeck if (regval < 0) 44*f5320701SGuenter Roeck return regval; 45*f5320701SGuenter Roeck *val = regval; 46*f5320701SGuenter Roeck return 0; 4751c2a487SLars-Peter Clausen } 48983b97beSHartmut Knaack 49*f5320701SGuenter Roeck static int adt7410_reg_write(void *context, unsigned int reg, unsigned int val) 5051c2a487SLars-Peter Clausen { 51*f5320701SGuenter Roeck struct i2c_client *client = context; 52*f5320701SGuenter Roeck int ret; 53*f5320701SGuenter Roeck 54*f5320701SGuenter Roeck switch (reg) { 55*f5320701SGuenter Roeck case ADT7X10_TEMPERATURE: 56*f5320701SGuenter Roeck case ADT7X10_T_ALARM_HIGH: 57*f5320701SGuenter Roeck case ADT7X10_T_ALARM_LOW: 58*f5320701SGuenter Roeck case ADT7X10_T_CRIT: 59*f5320701SGuenter Roeck ret = i2c_smbus_write_word_swapped(client, reg, val); 60*f5320701SGuenter Roeck break; 61*f5320701SGuenter Roeck default: 62*f5320701SGuenter Roeck ret = i2c_smbus_write_byte_data(client, reg, val); 63*f5320701SGuenter Roeck break; 64*f5320701SGuenter Roeck } 65*f5320701SGuenter Roeck return ret; 6651c2a487SLars-Peter Clausen } 67983b97beSHartmut Knaack 68*f5320701SGuenter Roeck static const struct regmap_config adt7410_regmap_config = { 69*f5320701SGuenter Roeck .reg_bits = 8, 70*f5320701SGuenter Roeck .val_bits = 16, 71*f5320701SGuenter Roeck .max_register = ADT7X10_ID, 72*f5320701SGuenter Roeck .cache_type = REGCACHE_RBTREE, 73*f5320701SGuenter Roeck .volatile_reg = adt7410_regmap_is_volatile, 74*f5320701SGuenter Roeck .reg_read = adt7410_reg_read, 75*f5320701SGuenter Roeck .reg_write = adt7410_reg_write, 76983b97beSHartmut Knaack }; 77983b97beSHartmut Knaack 7867487038SStephen Kitt static int adt7410_i2c_probe(struct i2c_client *client) 79983b97beSHartmut Knaack { 80*f5320701SGuenter Roeck struct regmap *regmap; 81983b97beSHartmut Knaack 82*f5320701SGuenter Roeck regmap = devm_regmap_init(&client->dev, NULL, client, 83*f5320701SGuenter Roeck &adt7410_regmap_config); 84*f5320701SGuenter Roeck if (IS_ERR(regmap)) 85*f5320701SGuenter Roeck return PTR_ERR(regmap); 86*f5320701SGuenter Roeck 87*f5320701SGuenter Roeck return adt7x10_probe(&client->dev, NULL, 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