xref: /openbmc/linux/drivers/hwmon/max6650.c (revision 1975d167)
174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2d20620deSHans-Juergen Koch /*
3d20620deSHans-Juergen Koch  * max6650.c - Part of lm_sensors, Linux kernel modules for hardware
4d20620deSHans-Juergen Koch  *             monitoring.
5d20620deSHans-Juergen Koch  *
62aa25c22SHans J. Koch  * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
7d20620deSHans-Juergen Koch  *
8d20620deSHans-Juergen Koch  * based on code written by John Morris <john.morris@spirentcom.com>
9d20620deSHans-Juergen Koch  * Copyright (c) 2003 Spirent Communications
10d20620deSHans-Juergen Koch  * and Claus Gindhart <claus.gindhart@kontron.com>
11d20620deSHans-Juergen Koch  *
12d20620deSHans-Juergen Koch  * This module has only been tested with the MAX6650 chip. It should
13d20620deSHans-Juergen Koch  * also work with the MAX6651. It does not distinguish max6650 and max6651
14d20620deSHans-Juergen Koch  * chips.
15d20620deSHans-Juergen Koch  *
1652b5226fSChristian Engelmayer  * The datasheet was last seen at:
17d20620deSHans-Juergen Koch  *
18d20620deSHans-Juergen Koch  *        http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
19d20620deSHans-Juergen Koch  */
20d20620deSHans-Juergen Koch 
21d20620deSHans-Juergen Koch #include <linux/module.h>
22d20620deSHans-Juergen Koch #include <linux/init.h>
23d20620deSHans-Juergen Koch #include <linux/slab.h>
24d20620deSHans-Juergen Koch #include <linux/jiffies.h>
25d20620deSHans-Juergen Koch #include <linux/i2c.h>
26d20620deSHans-Juergen Koch #include <linux/hwmon.h>
27d20620deSHans-Juergen Koch #include <linux/hwmon-sysfs.h>
28d20620deSHans-Juergen Koch #include <linux/err.h>
29a6cdeefeSMike Looijmans #include <linux/of_device.h>
304f8d374bSJean-Francois Dagenais #include <linux/thermal.h>
31d20620deSHans-Juergen Koch 
32d20620deSHans-Juergen Koch /*
33d20620deSHans-Juergen Koch  * Insmod parameters
34d20620deSHans-Juergen Koch  */
35d20620deSHans-Juergen Koch 
36d20620deSHans-Juergen Koch /* fan_voltage: 5=5V fan, 12=12V fan, 0=don't change */
37d20620deSHans-Juergen Koch static int fan_voltage;
38d20620deSHans-Juergen Koch /* prescaler: Possible values are 1, 2, 4, 8, 16 or 0 for don't change */
39d20620deSHans-Juergen Koch static int prescaler;
40a6cdeefeSMike Looijmans /* clock: The clock frequency of the chip (max6651 can be clocked externally) */
41d20620deSHans-Juergen Koch static int clock = 254000;
42d20620deSHans-Juergen Koch 
430f50b2e8SGuenter Roeck module_param(fan_voltage, int, 0444);
440f50b2e8SGuenter Roeck module_param(prescaler, int, 0444);
450f50b2e8SGuenter Roeck module_param(clock, int, 0444);
46d20620deSHans-Juergen Koch 
47d20620deSHans-Juergen Koch /*
48d20620deSHans-Juergen Koch  * MAX 6650/6651 registers
49d20620deSHans-Juergen Koch  */
50d20620deSHans-Juergen Koch 
51d20620deSHans-Juergen Koch #define MAX6650_REG_SPEED	0x00
52d20620deSHans-Juergen Koch #define MAX6650_REG_CONFIG	0x02
53d20620deSHans-Juergen Koch #define MAX6650_REG_GPIO_DEF	0x04
54d20620deSHans-Juergen Koch #define MAX6650_REG_DAC		0x06
55d20620deSHans-Juergen Koch #define MAX6650_REG_ALARM_EN	0x08
56d20620deSHans-Juergen Koch #define MAX6650_REG_ALARM	0x0A
57d20620deSHans-Juergen Koch #define MAX6650_REG_TACH0	0x0C
58d20620deSHans-Juergen Koch #define MAX6650_REG_TACH1	0x0E
59d20620deSHans-Juergen Koch #define MAX6650_REG_TACH2	0x10
60d20620deSHans-Juergen Koch #define MAX6650_REG_TACH3	0x12
61d20620deSHans-Juergen Koch #define MAX6650_REG_GPIO_STAT	0x14
62d20620deSHans-Juergen Koch #define MAX6650_REG_COUNT	0x16
63d20620deSHans-Juergen Koch 
64d20620deSHans-Juergen Koch /*
65d20620deSHans-Juergen Koch  * Config register bits
66d20620deSHans-Juergen Koch  */
67d20620deSHans-Juergen Koch 
68d20620deSHans-Juergen Koch #define MAX6650_CFG_V12			0x08
69d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_MASK	0x07
70d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_2		0x01
71d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_4		0x02
72d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_8		0x03
73d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_16	0x04
74d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_MASK		0x30
75d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_ON		0x00
76d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_OFF		0x10
77d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_CLOSED_LOOP	0x20
78d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_OPEN_LOOP	0x30
79d20620deSHans-Juergen Koch #define MAX6650_COUNT_MASK		0x03
80d20620deSHans-Juergen Koch 
8152b5226fSChristian Engelmayer /*
8252b5226fSChristian Engelmayer  * Alarm status register bits
8352b5226fSChristian Engelmayer  */
8452b5226fSChristian Engelmayer 
8552b5226fSChristian Engelmayer #define MAX6650_ALRM_MAX	0x01
8652b5226fSChristian Engelmayer #define MAX6650_ALRM_MIN	0x02
8752b5226fSChristian Engelmayer #define MAX6650_ALRM_TACH	0x04
8852b5226fSChristian Engelmayer #define MAX6650_ALRM_GPIO1	0x08
8952b5226fSChristian Engelmayer #define MAX6650_ALRM_GPIO2	0x10
9052b5226fSChristian Engelmayer 
91d20620deSHans-Juergen Koch /* Minimum and maximum values of the FAN-RPM */
92d20620deSHans-Juergen Koch #define FAN_RPM_MIN 240
93d20620deSHans-Juergen Koch #define FAN_RPM_MAX 30000
94d20620deSHans-Juergen Koch 
95b2905bb8SGuenter Roeck #define DIV_FROM_REG(reg)	(1 << ((reg) & 7))
96b2905bb8SGuenter Roeck #define DAC_LIMIT(v12)		((v12) ? 180 : 76)
97d20620deSHans-Juergen Koch 
98d20620deSHans-Juergen Koch /*
99d20620deSHans-Juergen Koch  * Client data (each client gets its own)
100d20620deSHans-Juergen Koch  */
101d20620deSHans-Juergen Koch 
102bafda5d0SGuenter Roeck struct max6650_data {
10317eaa25cSGuenter Roeck 	struct i2c_client *client;
104228b9e19SGuenter Roeck 	struct mutex update_lock; /* protect alarm register updates */
1059c084daeSJean Delvare 	int nr_fans;
106bf8c9edaSGuenter Roeck 	bool valid; /* false until following fields are valid */
107d20620deSHans-Juergen Koch 	unsigned long last_updated; /* in jiffies */
108d20620deSHans-Juergen Koch 
109d20620deSHans-Juergen Koch 	/* register values */
110d20620deSHans-Juergen Koch 	u8 speed;
111d20620deSHans-Juergen Koch 	u8 config;
112d20620deSHans-Juergen Koch 	u8 tach[4];
113d20620deSHans-Juergen Koch 	u8 count;
114d20620deSHans-Juergen Koch 	u8 dac;
11552b5226fSChristian Engelmayer 	u8 alarm;
116f5b20b11SGuenter Roeck 	u8 alarm_en;
1174f8d374bSJean-Francois Dagenais 	unsigned long cooling_dev_state;
118d20620deSHans-Juergen Koch };
119d20620deSHans-Juergen Koch 
1201577f94bSGuenter Roeck static const u8 tach_reg[] = {
1211577f94bSGuenter Roeck 	MAX6650_REG_TACH0,
1221577f94bSGuenter Roeck 	MAX6650_REG_TACH1,
1231577f94bSGuenter Roeck 	MAX6650_REG_TACH2,
1241577f94bSGuenter Roeck 	MAX6650_REG_TACH3,
1251577f94bSGuenter Roeck };
1261577f94bSGuenter Roeck 
1272720ce7eSGuenter Roeck static const struct of_device_id __maybe_unused max6650_dt_match[] = {
128a6cdeefeSMike Looijmans 	{
129a6cdeefeSMike Looijmans 		.compatible = "maxim,max6650",
130a6cdeefeSMike Looijmans 		.data = (void *)1
131a6cdeefeSMike Looijmans 	},
132a6cdeefeSMike Looijmans 	{
133a6cdeefeSMike Looijmans 		.compatible = "maxim,max6651",
134a6cdeefeSMike Looijmans 		.data = (void *)4
135a6cdeefeSMike Looijmans 	},
136a6cdeefeSMike Looijmans 	{ },
137a6cdeefeSMike Looijmans };
138a6cdeefeSMike Looijmans MODULE_DEVICE_TABLE(of, max6650_dt_match);
139a6cdeefeSMike Looijmans 
dac_to_pwm(int dac,bool v12)140b2905bb8SGuenter Roeck static int dac_to_pwm(int dac, bool v12)
141b2905bb8SGuenter Roeck {
142b2905bb8SGuenter Roeck 	/*
143b2905bb8SGuenter Roeck 	 * Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans.
144b2905bb8SGuenter Roeck 	 * Lower DAC values mean higher speeds.
145b2905bb8SGuenter Roeck 	 */
146b2905bb8SGuenter Roeck 	return clamp_val(255 - (255 * dac) / DAC_LIMIT(v12), 0, 255);
147b2905bb8SGuenter Roeck }
148b2905bb8SGuenter Roeck 
pwm_to_dac(unsigned int pwm,bool v12)149b2905bb8SGuenter Roeck static u8 pwm_to_dac(unsigned int pwm, bool v12)
150b2905bb8SGuenter Roeck {
151b2905bb8SGuenter Roeck 	int limit = DAC_LIMIT(v12);
152b2905bb8SGuenter Roeck 
153b2905bb8SGuenter Roeck 	return limit - (limit * pwm) / 255;
154b2905bb8SGuenter Roeck }
155b2905bb8SGuenter Roeck 
max6650_update_device(struct device * dev)1561577f94bSGuenter Roeck static struct max6650_data *max6650_update_device(struct device *dev)
1571577f94bSGuenter Roeck {
15817eaa25cSGuenter Roeck 	struct max6650_data *data = dev_get_drvdata(dev);
15917eaa25cSGuenter Roeck 	struct i2c_client *client = data->client;
1600c4a71d3SGuenter Roeck 	int reg, err = 0;
1611577f94bSGuenter Roeck 	int i;
1621577f94bSGuenter Roeck 
1631577f94bSGuenter Roeck 	mutex_lock(&data->update_lock);
1641577f94bSGuenter Roeck 
1651577f94bSGuenter Roeck 	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
1661577f94bSGuenter Roeck 		for (i = 0; i < data->nr_fans; i++) {
1670c4a71d3SGuenter Roeck 			reg = i2c_smbus_read_byte_data(client, tach_reg[i]);
1680c4a71d3SGuenter Roeck 			if (reg < 0) {
1690c4a71d3SGuenter Roeck 				err = reg;
1700c4a71d3SGuenter Roeck 				goto error;
1710c4a71d3SGuenter Roeck 			}
1720c4a71d3SGuenter Roeck 			data->tach[i] = reg;
1731577f94bSGuenter Roeck 		}
1741577f94bSGuenter Roeck 
1751577f94bSGuenter Roeck 		/*
1761577f94bSGuenter Roeck 		 * Alarms are cleared on read in case the condition that
1771577f94bSGuenter Roeck 		 * caused the alarm is removed. Keep the value latched here
1781577f94bSGuenter Roeck 		 * for providing the register through different alarm files.
1791577f94bSGuenter Roeck 		 */
1800c4a71d3SGuenter Roeck 		reg = i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM);
1810c4a71d3SGuenter Roeck 		if (reg < 0) {
1820c4a71d3SGuenter Roeck 			err = reg;
1830c4a71d3SGuenter Roeck 			goto error;
1840c4a71d3SGuenter Roeck 		}
1850c4a71d3SGuenter Roeck 		data->alarm |= reg;
1861577f94bSGuenter Roeck 		data->last_updated = jiffies;
187bf8c9edaSGuenter Roeck 		data->valid = true;
1881577f94bSGuenter Roeck 	}
1891577f94bSGuenter Roeck 
1900c4a71d3SGuenter Roeck error:
1911577f94bSGuenter Roeck 	mutex_unlock(&data->update_lock);
1920c4a71d3SGuenter Roeck 	if (err)
1930c4a71d3SGuenter Roeck 		data = ERR_PTR(err);
1941577f94bSGuenter Roeck 	return data;
1951577f94bSGuenter Roeck }
1961577f94bSGuenter Roeck 
19720005cc5SMike Looijmans /*
19820005cc5SMike Looijmans  * Change the operating mode of the chip (if needed).
19920005cc5SMike Looijmans  * mode is one of the MAX6650_CFG_MODE_* values.
20020005cc5SMike Looijmans  */
max6650_set_operating_mode(struct max6650_data * data,u8 mode)20120005cc5SMike Looijmans static int max6650_set_operating_mode(struct max6650_data *data, u8 mode)
20220005cc5SMike Looijmans {
20320005cc5SMike Looijmans 	int result;
20420005cc5SMike Looijmans 	u8 config = data->config;
20520005cc5SMike Looijmans 
20620005cc5SMike Looijmans 	if (mode == (config & MAX6650_CFG_MODE_MASK))
20720005cc5SMike Looijmans 		return 0;
20820005cc5SMike Looijmans 
20920005cc5SMike Looijmans 	config = (config & ~MAX6650_CFG_MODE_MASK) | mode;
21020005cc5SMike Looijmans 
21120005cc5SMike Looijmans 	result = i2c_smbus_write_byte_data(data->client, MAX6650_REG_CONFIG,
21220005cc5SMike Looijmans 					   config);
21320005cc5SMike Looijmans 	if (result < 0)
21420005cc5SMike Looijmans 		return result;
21520005cc5SMike Looijmans 
21620005cc5SMike Looijmans 	data->config = config;
21720005cc5SMike Looijmans 
21820005cc5SMike Looijmans 	return 0;
21920005cc5SMike Looijmans }
22020005cc5SMike Looijmans 
221d20620deSHans-Juergen Koch /*
222d20620deSHans-Juergen Koch  * Set the fan speed to the specified RPM (or read back the RPM setting).
223d20620deSHans-Juergen Koch  * This works in closed loop mode only. Use pwm1 for open loop speed setting.
224d20620deSHans-Juergen Koch  *
225d20620deSHans-Juergen Koch  * The MAX6650/1 will automatically control fan speed when in closed loop
226d20620deSHans-Juergen Koch  * mode.
227d20620deSHans-Juergen Koch  *
228d20620deSHans-Juergen Koch  * Assumptions:
229d20620deSHans-Juergen Koch  *
230d20620deSHans-Juergen Koch  * 1) The MAX6650/1 internal 254kHz clock frequency is set correctly. Use
231d20620deSHans-Juergen Koch  *    the clock module parameter if you need to fine tune this.
232d20620deSHans-Juergen Koch  *
233d20620deSHans-Juergen Koch  * 2) The prescaler (low three bits of the config register) has already
234d20620deSHans-Juergen Koch  *    been set to an appropriate value. Use the prescaler module parameter
235d20620deSHans-Juergen Koch  *    if your BIOS doesn't initialize the chip properly.
236d20620deSHans-Juergen Koch  *
237d20620deSHans-Juergen Koch  * The relevant equations are given on pages 21 and 22 of the datasheet.
238d20620deSHans-Juergen Koch  *
239d20620deSHans-Juergen Koch  * From the datasheet, the relevant equation when in regulation is:
240d20620deSHans-Juergen Koch  *
241d20620deSHans-Juergen Koch  *    [fCLK / (128 x (KTACH + 1))] = 2 x FanSpeed / KSCALE
242d20620deSHans-Juergen Koch  *
243d20620deSHans-Juergen Koch  * where:
244d20620deSHans-Juergen Koch  *
245d20620deSHans-Juergen Koch  *    fCLK is the oscillator frequency (either the 254kHz internal
246d20620deSHans-Juergen Koch  *         oscillator or the externally applied clock)
247d20620deSHans-Juergen Koch  *
248d20620deSHans-Juergen Koch  *    KTACH is the value in the speed register
249d20620deSHans-Juergen Koch  *
250d20620deSHans-Juergen Koch  *    FanSpeed is the speed of the fan in rps
251d20620deSHans-Juergen Koch  *
252d20620deSHans-Juergen Koch  *    KSCALE is the prescaler value (1, 2, 4, 8, or 16)
253d20620deSHans-Juergen Koch  *
254d20620deSHans-Juergen Koch  * When reading, we need to solve for FanSpeed. When writing, we need to
255d20620deSHans-Juergen Koch  * solve for KTACH.
256d20620deSHans-Juergen Koch  *
257d20620deSHans-Juergen Koch  * Note: this tachometer is completely separate from the tachometers
258d20620deSHans-Juergen Koch  * used to measure the fan speeds. Only one fan's speed (fan1) is
259d20620deSHans-Juergen Koch  * controlled.
260d20620deSHans-Juergen Koch  */
261d20620deSHans-Juergen Koch 
max6650_set_target(struct max6650_data * data,unsigned long rpm)26220005cc5SMike Looijmans static int max6650_set_target(struct max6650_data *data, unsigned long rpm)
263d20620deSHans-Juergen Koch {
264d20620deSHans-Juergen Koch 	int kscale, ktach;
265bafda5d0SGuenter Roeck 
26620005cc5SMike Looijmans 	if (rpm == 0)
26720005cc5SMike Looijmans 		return max6650_set_operating_mode(data, MAX6650_CFG_MODE_OFF);
268d20620deSHans-Juergen Koch 
2692a844c14SGuenter Roeck 	rpm = clamp_val(rpm, FAN_RPM_MIN, FAN_RPM_MAX);
270d20620deSHans-Juergen Koch 
271d20620deSHans-Juergen Koch 	/*
272d20620deSHans-Juergen Koch 	 * Divide the required speed by 60 to get from rpm to rps, then
273d20620deSHans-Juergen Koch 	 * use the datasheet equation:
274d20620deSHans-Juergen Koch 	 *
275d20620deSHans-Juergen Koch 	 *     KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1
276d20620deSHans-Juergen Koch 	 */
277d20620deSHans-Juergen Koch 
278d20620deSHans-Juergen Koch 	kscale = DIV_FROM_REG(data->config);
279d20620deSHans-Juergen Koch 	ktach = ((clock * kscale) / (256 * rpm / 60)) - 1;
280d20620deSHans-Juergen Koch 	if (ktach < 0)
281d20620deSHans-Juergen Koch 		ktach = 0;
282d20620deSHans-Juergen Koch 	if (ktach > 255)
283d20620deSHans-Juergen Koch 		ktach = 255;
284d20620deSHans-Juergen Koch 	data->speed = ktach;
285d20620deSHans-Juergen Koch 
28620005cc5SMike Looijmans 	return i2c_smbus_write_byte_data(data->client, MAX6650_REG_SPEED,
28720005cc5SMike Looijmans 					 data->speed);
28820005cc5SMike Looijmans }
28920005cc5SMike Looijmans 
290d20620deSHans-Juergen Koch /*
291e193acb3SGuenter Roeck  * Get gpio alarm status:
29252b5226fSChristian Engelmayer  * Possible values:
29352b5226fSChristian Engelmayer  * 0 = no alarm
29452b5226fSChristian Engelmayer  * 1 = alarm
29552b5226fSChristian Engelmayer  */
29652b5226fSChristian Engelmayer 
alarm_show(struct device * dev,struct device_attribute * devattr,char * buf)29744007117SGuenter Roeck static ssize_t alarm_show(struct device *dev,
29844007117SGuenter Roeck 			  struct device_attribute *devattr, char *buf)
29952b5226fSChristian Engelmayer {
30052b5226fSChristian Engelmayer 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
30152b5226fSChristian Engelmayer 	struct max6650_data *data = max6650_update_device(dev);
3020c4a71d3SGuenter Roeck 	bool alarm;
30352b5226fSChristian Engelmayer 
3040c4a71d3SGuenter Roeck 	if (IS_ERR(data))
3050c4a71d3SGuenter Roeck 		return PTR_ERR(data);
3060c4a71d3SGuenter Roeck 
3070c4a71d3SGuenter Roeck 	alarm = data->alarm & attr->index;
3080d5cc938SGuenter Roeck 	if (alarm) {
30952b5226fSChristian Engelmayer 		mutex_lock(&data->update_lock);
31052b5226fSChristian Engelmayer 		data->alarm &= ~attr->index;
3110d5cc938SGuenter Roeck 		data->valid = false;
31252b5226fSChristian Engelmayer 		mutex_unlock(&data->update_lock);
31352b5226fSChristian Engelmayer 	}
31452b5226fSChristian Engelmayer 
31552b5226fSChristian Engelmayer 	return sprintf(buf, "%d\n", alarm);
31652b5226fSChristian Engelmayer }
31752b5226fSChristian Engelmayer 
31844007117SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(gpio1_alarm, alarm, MAX6650_ALRM_GPIO1);
31944007117SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(gpio2_alarm, alarm, MAX6650_ALRM_GPIO2);
320d20620deSHans-Juergen Koch 
max6650_attrs_visible(struct kobject * kobj,struct attribute * a,int n)321587a1f16SAl Viro static umode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a,
32252b5226fSChristian Engelmayer 				     int n)
32352b5226fSChristian Engelmayer {
324f1fc688cSTian Tao 	struct device *dev = kobj_to_dev(kobj);
32517eaa25cSGuenter Roeck 	struct max6650_data *data = dev_get_drvdata(dev);
32652b5226fSChristian Engelmayer 	struct device_attribute *devattr;
32752b5226fSChristian Engelmayer 
32852b5226fSChristian Engelmayer 	/*
32952b5226fSChristian Engelmayer 	 * Hide the alarms that have not been enabled by the firmware
33052b5226fSChristian Engelmayer 	 */
33152b5226fSChristian Engelmayer 
33252b5226fSChristian Engelmayer 	devattr = container_of(a, struct device_attribute, attr);
333e193acb3SGuenter Roeck 	if (devattr == &sensor_dev_attr_gpio1_alarm.dev_attr ||
334e193acb3SGuenter Roeck 	    devattr == &sensor_dev_attr_gpio2_alarm.dev_attr) {
335f5b20b11SGuenter Roeck 		if (!(data->alarm_en & to_sensor_dev_attr(devattr)->index))
33652b5226fSChristian Engelmayer 			return 0;
33752b5226fSChristian Engelmayer 	}
33852b5226fSChristian Engelmayer 
33952b5226fSChristian Engelmayer 	return a->mode;
34052b5226fSChristian Engelmayer }
341d20620deSHans-Juergen Koch 
342d20620deSHans-Juergen Koch static struct attribute *max6650_attrs[] = {
34352b5226fSChristian Engelmayer 	&sensor_dev_attr_gpio1_alarm.dev_attr.attr,
34452b5226fSChristian Engelmayer 	&sensor_dev_attr_gpio2_alarm.dev_attr.attr,
345d20620deSHans-Juergen Koch 	NULL
346d20620deSHans-Juergen Koch };
347d20620deSHans-Juergen Koch 
34817eaa25cSGuenter Roeck static const struct attribute_group max6650_group = {
349d20620deSHans-Juergen Koch 	.attrs = max6650_attrs,
35052b5226fSChristian Engelmayer 	.is_visible = max6650_attrs_visible,
351d20620deSHans-Juergen Koch };
352d20620deSHans-Juergen Koch 
353e193acb3SGuenter Roeck static const struct attribute_group *max6650_groups[] = {
354e193acb3SGuenter Roeck 	&max6650_group,
3559c084daeSJean Delvare 	NULL
3569c084daeSJean Delvare };
3579c084daeSJean Delvare 
max6650_init_client(struct max6650_data * data,struct i2c_client * client)35817eaa25cSGuenter Roeck static int max6650_init_client(struct max6650_data *data,
35917eaa25cSGuenter Roeck 			       struct i2c_client *client)
360d20620deSHans-Juergen Koch {
36171ba0f31SGuenter Roeck 	struct device *dev = &client->dev;
362b9d8de4aSGuenter Roeck 	int reg;
363b9d8de4aSGuenter Roeck 	int err;
364a6cdeefeSMike Looijmans 	u32 voltage;
365a6cdeefeSMike Looijmans 	u32 prescale;
36620005cc5SMike Looijmans 	u32 target_rpm;
367a6cdeefeSMike Looijmans 
368a6cdeefeSMike Looijmans 	if (of_property_read_u32(dev->of_node, "maxim,fan-microvolt",
369a6cdeefeSMike Looijmans 				 &voltage))
370a6cdeefeSMike Looijmans 		voltage = fan_voltage;
371a6cdeefeSMike Looijmans 	else
372a6cdeefeSMike Looijmans 		voltage /= 1000000; /* Microvolts to volts */
373a6cdeefeSMike Looijmans 	if (of_property_read_u32(dev->of_node, "maxim,fan-prescale",
374a6cdeefeSMike Looijmans 				 &prescale))
375a6cdeefeSMike Looijmans 		prescale = prescaler;
376d20620deSHans-Juergen Koch 
377b9d8de4aSGuenter Roeck 	reg = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG);
378b9d8de4aSGuenter Roeck 	if (reg < 0) {
379b9d8de4aSGuenter Roeck 		dev_err(dev, "Error reading config register, aborting.\n");
380b9d8de4aSGuenter Roeck 		return reg;
381d20620deSHans-Juergen Koch 	}
382d20620deSHans-Juergen Koch 
383a6cdeefeSMike Looijmans 	switch (voltage) {
384d20620deSHans-Juergen Koch 	case 0:
385d20620deSHans-Juergen Koch 		break;
386d20620deSHans-Juergen Koch 	case 5:
387b9d8de4aSGuenter Roeck 		reg &= ~MAX6650_CFG_V12;
388d20620deSHans-Juergen Koch 		break;
389d20620deSHans-Juergen Koch 	case 12:
390b9d8de4aSGuenter Roeck 		reg |= MAX6650_CFG_V12;
391d20620deSHans-Juergen Koch 		break;
392d20620deSHans-Juergen Koch 	default:
393a6cdeefeSMike Looijmans 		dev_err(dev, "illegal value for fan_voltage (%d)\n", voltage);
394d20620deSHans-Juergen Koch 	}
395d20620deSHans-Juergen Koch 
396a6cdeefeSMike Looijmans 	switch (prescale) {
397d20620deSHans-Juergen Koch 	case 0:
398d20620deSHans-Juergen Koch 		break;
399d20620deSHans-Juergen Koch 	case 1:
400b9d8de4aSGuenter Roeck 		reg &= ~MAX6650_CFG_PRESCALER_MASK;
401d20620deSHans-Juergen Koch 		break;
402d20620deSHans-Juergen Koch 	case 2:
403b9d8de4aSGuenter Roeck 		reg = (reg & ~MAX6650_CFG_PRESCALER_MASK)
404d20620deSHans-Juergen Koch 			 | MAX6650_CFG_PRESCALER_2;
405d20620deSHans-Juergen Koch 		break;
406d20620deSHans-Juergen Koch 	case  4:
407b9d8de4aSGuenter Roeck 		reg = (reg & ~MAX6650_CFG_PRESCALER_MASK)
408d20620deSHans-Juergen Koch 			 | MAX6650_CFG_PRESCALER_4;
409d20620deSHans-Juergen Koch 		break;
410d20620deSHans-Juergen Koch 	case  8:
411b9d8de4aSGuenter Roeck 		reg = (reg & ~MAX6650_CFG_PRESCALER_MASK)
412d20620deSHans-Juergen Koch 			 | MAX6650_CFG_PRESCALER_8;
413d20620deSHans-Juergen Koch 		break;
414d20620deSHans-Juergen Koch 	case 16:
415b9d8de4aSGuenter Roeck 		reg = (reg & ~MAX6650_CFG_PRESCALER_MASK)
416d20620deSHans-Juergen Koch 			 | MAX6650_CFG_PRESCALER_16;
417d20620deSHans-Juergen Koch 		break;
418d20620deSHans-Juergen Koch 	default:
419a6cdeefeSMike Looijmans 		dev_err(dev, "illegal value for prescaler (%d)\n", prescale);
420d20620deSHans-Juergen Koch 	}
421d20620deSHans-Juergen Koch 
422a6cdeefeSMike Looijmans 	dev_info(dev, "Fan voltage: %dV, prescaler: %d.\n",
423b9d8de4aSGuenter Roeck 		 (reg & MAX6650_CFG_V12) ? 12 : 5,
424b9d8de4aSGuenter Roeck 		 1 << (reg & MAX6650_CFG_PRESCALER_MASK));
425d20620deSHans-Juergen Koch 
426b9d8de4aSGuenter Roeck 	err = i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, reg);
427b9d8de4aSGuenter Roeck 	if (err) {
42871ba0f31SGuenter Roeck 		dev_err(dev, "Config write error, aborting.\n");
429d20620deSHans-Juergen Koch 		return err;
430d20620deSHans-Juergen Koch 	}
431b9d8de4aSGuenter Roeck 	data->config = reg;
43262dbe505SGuenter Roeck 
43362dbe505SGuenter Roeck 	reg = i2c_smbus_read_byte_data(client, MAX6650_REG_SPEED);
43462dbe505SGuenter Roeck 	if (reg < 0) {
43562dbe505SGuenter Roeck 		dev_err(dev, "Failed to read speed register, aborting.\n");
43662dbe505SGuenter Roeck 		return reg;
43762dbe505SGuenter Roeck 	}
43862dbe505SGuenter Roeck 	data->speed = reg;
43962dbe505SGuenter Roeck 
44062dbe505SGuenter Roeck 	reg = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC);
44162dbe505SGuenter Roeck 	if (reg < 0) {
44262dbe505SGuenter Roeck 		dev_err(dev, "Failed to read DAC register, aborting.\n");
44362dbe505SGuenter Roeck 		return reg;
44462dbe505SGuenter Roeck 	}
44562dbe505SGuenter Roeck 	data->dac = reg;
44662dbe505SGuenter Roeck 
447b9d8de4aSGuenter Roeck 	reg = i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT);
448b9d8de4aSGuenter Roeck 	if (reg < 0) {
449b9d8de4aSGuenter Roeck 		dev_err(dev, "Failed to read count register, aborting.\n");
450b9d8de4aSGuenter Roeck 		return reg;
451b9d8de4aSGuenter Roeck 	}
452b9d8de4aSGuenter Roeck 	data->count = reg;
453d20620deSHans-Juergen Koch 
454f5b20b11SGuenter Roeck 	reg = i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN);
455f5b20b11SGuenter Roeck 	if (reg < 0) {
456f5b20b11SGuenter Roeck 		dev_err(dev, "Failed to read alarm configuration, aborting.\n");
457f5b20b11SGuenter Roeck 		return reg;
458f5b20b11SGuenter Roeck 	}
459f5b20b11SGuenter Roeck 	data->alarm_en = reg;
460f5b20b11SGuenter Roeck 
46120005cc5SMike Looijmans 	if (!of_property_read_u32(client->dev.of_node, "maxim,fan-target-rpm",
46220005cc5SMike Looijmans 				  &target_rpm)) {
46320005cc5SMike Looijmans 		max6650_set_target(data, target_rpm);
46420005cc5SMike Looijmans 		max6650_set_operating_mode(data, MAX6650_CFG_MODE_CLOSED_LOOP);
46520005cc5SMike Looijmans 	}
46620005cc5SMike Looijmans 
467d20620deSHans-Juergen Koch 	return 0;
468d20620deSHans-Juergen Koch }
469d20620deSHans-Juergen Koch 
max6650_get_max_state(struct thermal_cooling_device * cdev,unsigned long * state)4704f8d374bSJean-Francois Dagenais static int max6650_get_max_state(struct thermal_cooling_device *cdev,
4714f8d374bSJean-Francois Dagenais 				 unsigned long *state)
4724f8d374bSJean-Francois Dagenais {
4734f8d374bSJean-Francois Dagenais 	*state = 255;
4744f8d374bSJean-Francois Dagenais 
4754f8d374bSJean-Francois Dagenais 	return 0;
4764f8d374bSJean-Francois Dagenais }
4774f8d374bSJean-Francois Dagenais 
max6650_get_cur_state(struct thermal_cooling_device * cdev,unsigned long * state)4784f8d374bSJean-Francois Dagenais static int max6650_get_cur_state(struct thermal_cooling_device *cdev,
4794f8d374bSJean-Francois Dagenais 				 unsigned long *state)
4804f8d374bSJean-Francois Dagenais {
4814f8d374bSJean-Francois Dagenais 	struct max6650_data *data = cdev->devdata;
4824f8d374bSJean-Francois Dagenais 
4834f8d374bSJean-Francois Dagenais 	*state = data->cooling_dev_state;
4844f8d374bSJean-Francois Dagenais 
4854f8d374bSJean-Francois Dagenais 	return 0;
4864f8d374bSJean-Francois Dagenais }
4874f8d374bSJean-Francois Dagenais 
max6650_set_cur_state(struct thermal_cooling_device * cdev,unsigned long state)4884f8d374bSJean-Francois Dagenais static int max6650_set_cur_state(struct thermal_cooling_device *cdev,
4894f8d374bSJean-Francois Dagenais 				 unsigned long state)
4904f8d374bSJean-Francois Dagenais {
4914f8d374bSJean-Francois Dagenais 	struct max6650_data *data = cdev->devdata;
4924f8d374bSJean-Francois Dagenais 	struct i2c_client *client = data->client;
4934f8d374bSJean-Francois Dagenais 	int err;
4944f8d374bSJean-Francois Dagenais 
4954f8d374bSJean-Francois Dagenais 	state = clamp_val(state, 0, 255);
4964f8d374bSJean-Francois Dagenais 
4974f8d374bSJean-Francois Dagenais 	mutex_lock(&data->update_lock);
4984f8d374bSJean-Francois Dagenais 
499b2905bb8SGuenter Roeck 	data->dac = pwm_to_dac(state, data->config & MAX6650_CFG_V12);
5004f8d374bSJean-Francois Dagenais 	err = i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac);
5014f8d374bSJean-Francois Dagenais 	if (!err) {
5024f8d374bSJean-Francois Dagenais 		max6650_set_operating_mode(data, state ?
5034f8d374bSJean-Francois Dagenais 					   MAX6650_CFG_MODE_OPEN_LOOP :
5044f8d374bSJean-Francois Dagenais 					   MAX6650_CFG_MODE_OFF);
5054f8d374bSJean-Francois Dagenais 		data->cooling_dev_state = state;
5064f8d374bSJean-Francois Dagenais 	}
5074f8d374bSJean-Francois Dagenais 
5084f8d374bSJean-Francois Dagenais 	mutex_unlock(&data->update_lock);
5094f8d374bSJean-Francois Dagenais 
510b2905bb8SGuenter Roeck 	return err;
5114f8d374bSJean-Francois Dagenais }
5124f8d374bSJean-Francois Dagenais 
5134f8d374bSJean-Francois Dagenais static const struct thermal_cooling_device_ops max6650_cooling_ops = {
5144f8d374bSJean-Francois Dagenais 	.get_max_state = max6650_get_max_state,
5154f8d374bSJean-Francois Dagenais 	.get_cur_state = max6650_get_cur_state,
5164f8d374bSJean-Francois Dagenais 	.set_cur_state = max6650_set_cur_state,
5174f8d374bSJean-Francois Dagenais };
5184f8d374bSJean-Francois Dagenais 
max6650_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)519e193acb3SGuenter Roeck static int max6650_read(struct device *dev, enum hwmon_sensor_types type,
520e193acb3SGuenter Roeck 			u32 attr, int channel, long *val)
521e193acb3SGuenter Roeck {
522e193acb3SGuenter Roeck 	struct max6650_data *data = max6650_update_device(dev);
523e193acb3SGuenter Roeck 	int mode;
524e193acb3SGuenter Roeck 
5250c4a71d3SGuenter Roeck 	if (IS_ERR(data))
5260c4a71d3SGuenter Roeck 		return PTR_ERR(data);
5270c4a71d3SGuenter Roeck 
528e193acb3SGuenter Roeck 	switch (type) {
529e193acb3SGuenter Roeck 	case hwmon_pwm:
530e193acb3SGuenter Roeck 		switch (attr) {
531e193acb3SGuenter Roeck 		case hwmon_pwm_input:
532e193acb3SGuenter Roeck 			*val = dac_to_pwm(data->dac,
533e193acb3SGuenter Roeck 					  data->config & MAX6650_CFG_V12);
534e193acb3SGuenter Roeck 			break;
535e193acb3SGuenter Roeck 		case hwmon_pwm_enable:
536e193acb3SGuenter Roeck 			/*
537e193acb3SGuenter Roeck 			 * Possible values:
538e193acb3SGuenter Roeck 			 * 0 = Fan always on
539e193acb3SGuenter Roeck 			 * 1 = Open loop, Voltage is set according to speed,
540e193acb3SGuenter Roeck 			 *     not regulated.
541e193acb3SGuenter Roeck 			 * 2 = Closed loop, RPM for all fans regulated by fan1
542e193acb3SGuenter Roeck 			 *     tachometer
543e193acb3SGuenter Roeck 			 * 3 = Fan off
544e193acb3SGuenter Roeck 			 */
545e193acb3SGuenter Roeck 			mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4;
546e193acb3SGuenter Roeck 			*val = (4 - mode) & 3; /* {0 1 2 3} -> {0 3 2 1} */
547e193acb3SGuenter Roeck 			break;
548e193acb3SGuenter Roeck 		default:
549e193acb3SGuenter Roeck 			return -EOPNOTSUPP;
550e193acb3SGuenter Roeck 		}
551e193acb3SGuenter Roeck 		break;
552e193acb3SGuenter Roeck 	case hwmon_fan:
553e193acb3SGuenter Roeck 		switch (attr) {
554e193acb3SGuenter Roeck 		case hwmon_fan_input:
555e193acb3SGuenter Roeck 			/*
556e193acb3SGuenter Roeck 			 * Calculation details:
557e193acb3SGuenter Roeck 			 *
558e193acb3SGuenter Roeck 			 * Each tachometer counts over an interval given by the
559e193acb3SGuenter Roeck 			 * "count" register (0.25, 0.5, 1 or 2 seconds).
560e193acb3SGuenter Roeck 			 * The driver assumes that the fans produce two pulses
561e193acb3SGuenter Roeck 			 * per revolution (this seems to be the most common).
562e193acb3SGuenter Roeck 			 */
563e193acb3SGuenter Roeck 			*val = DIV_ROUND_CLOSEST(data->tach[channel] * 120,
564e193acb3SGuenter Roeck 						 DIV_FROM_REG(data->count));
565e193acb3SGuenter Roeck 			break;
566e193acb3SGuenter Roeck 		case hwmon_fan_div:
567e193acb3SGuenter Roeck 			*val = DIV_FROM_REG(data->count);
568e193acb3SGuenter Roeck 			break;
569e193acb3SGuenter Roeck 		case hwmon_fan_target:
570e193acb3SGuenter Roeck 			/*
571e193acb3SGuenter Roeck 			 * Use the datasheet equation:
572e193acb3SGuenter Roeck 			 *    FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)]
573e193acb3SGuenter Roeck 			 * then multiply by 60 to give rpm.
574e193acb3SGuenter Roeck 			 */
575e193acb3SGuenter Roeck 			*val = 60 * DIV_FROM_REG(data->config) * clock /
576e193acb3SGuenter Roeck 				(256 * (data->speed + 1));
577e193acb3SGuenter Roeck 			break;
578e193acb3SGuenter Roeck 		case hwmon_fan_min_alarm:
579e193acb3SGuenter Roeck 			*val = !!(data->alarm & MAX6650_ALRM_MIN);
580e193acb3SGuenter Roeck 			data->alarm &= ~MAX6650_ALRM_MIN;
581e193acb3SGuenter Roeck 			data->valid = false;
582e193acb3SGuenter Roeck 			break;
583e193acb3SGuenter Roeck 		case hwmon_fan_max_alarm:
584e193acb3SGuenter Roeck 			*val = !!(data->alarm & MAX6650_ALRM_MAX);
585e193acb3SGuenter Roeck 			data->alarm &= ~MAX6650_ALRM_MAX;
586e193acb3SGuenter Roeck 			data->valid = false;
587e193acb3SGuenter Roeck 			break;
588e193acb3SGuenter Roeck 		case hwmon_fan_fault:
589e193acb3SGuenter Roeck 			*val = !!(data->alarm & MAX6650_ALRM_TACH);
590e193acb3SGuenter Roeck 			data->alarm &= ~MAX6650_ALRM_TACH;
591e193acb3SGuenter Roeck 			data->valid = false;
592e193acb3SGuenter Roeck 			break;
593e193acb3SGuenter Roeck 		default:
594e193acb3SGuenter Roeck 			return -EOPNOTSUPP;
595e193acb3SGuenter Roeck 		}
596e193acb3SGuenter Roeck 		break;
597e193acb3SGuenter Roeck 	default:
598e193acb3SGuenter Roeck 		return -EOPNOTSUPP;
599e193acb3SGuenter Roeck 	}
600e193acb3SGuenter Roeck 	return 0;
601e193acb3SGuenter Roeck }
602e193acb3SGuenter Roeck 
603e193acb3SGuenter Roeck static const u8 max6650_pwm_modes[] = {
604e193acb3SGuenter Roeck 	MAX6650_CFG_MODE_ON,
605e193acb3SGuenter Roeck 	MAX6650_CFG_MODE_OPEN_LOOP,
606e193acb3SGuenter Roeck 	MAX6650_CFG_MODE_CLOSED_LOOP,
607e193acb3SGuenter Roeck 	MAX6650_CFG_MODE_OFF,
608e193acb3SGuenter Roeck };
609e193acb3SGuenter Roeck 
max6650_write(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long val)610e193acb3SGuenter Roeck static int max6650_write(struct device *dev, enum hwmon_sensor_types type,
611e193acb3SGuenter Roeck 			 u32 attr, int channel, long val)
612e193acb3SGuenter Roeck {
613e193acb3SGuenter Roeck 	struct max6650_data *data = dev_get_drvdata(dev);
614e193acb3SGuenter Roeck 	int ret = 0;
615e193acb3SGuenter Roeck 	u8 reg;
616e193acb3SGuenter Roeck 
617e193acb3SGuenter Roeck 	mutex_lock(&data->update_lock);
618e193acb3SGuenter Roeck 
619e193acb3SGuenter Roeck 	switch (type) {
620e193acb3SGuenter Roeck 	case hwmon_pwm:
621e193acb3SGuenter Roeck 		switch (attr) {
622e193acb3SGuenter Roeck 		case hwmon_pwm_input:
623e193acb3SGuenter Roeck 			reg = pwm_to_dac(clamp_val(val, 0, 255),
624e193acb3SGuenter Roeck 					 data->config & MAX6650_CFG_V12);
625e193acb3SGuenter Roeck 			ret = i2c_smbus_write_byte_data(data->client,
626e193acb3SGuenter Roeck 							MAX6650_REG_DAC, reg);
627e193acb3SGuenter Roeck 			if (ret)
628e193acb3SGuenter Roeck 				break;
629e193acb3SGuenter Roeck 			data->dac = reg;
630e193acb3SGuenter Roeck 			break;
631e193acb3SGuenter Roeck 		case hwmon_pwm_enable:
632e193acb3SGuenter Roeck 			if (val < 0 || val >= ARRAY_SIZE(max6650_pwm_modes)) {
633e193acb3SGuenter Roeck 				ret = -EINVAL;
634e193acb3SGuenter Roeck 				break;
635e193acb3SGuenter Roeck 			}
636e193acb3SGuenter Roeck 			ret = max6650_set_operating_mode(data,
637e193acb3SGuenter Roeck 						max6650_pwm_modes[val]);
638e193acb3SGuenter Roeck 			break;
639e193acb3SGuenter Roeck 		default:
640e193acb3SGuenter Roeck 			ret = -EOPNOTSUPP;
641e193acb3SGuenter Roeck 			break;
642e193acb3SGuenter Roeck 		}
643e193acb3SGuenter Roeck 		break;
644e193acb3SGuenter Roeck 	case hwmon_fan:
645e193acb3SGuenter Roeck 		switch (attr) {
646e193acb3SGuenter Roeck 		case hwmon_fan_div:
647e193acb3SGuenter Roeck 			switch (val) {
648e193acb3SGuenter Roeck 			case 1:
649e193acb3SGuenter Roeck 				reg = 0;
650e193acb3SGuenter Roeck 				break;
651e193acb3SGuenter Roeck 			case 2:
652e193acb3SGuenter Roeck 				reg = 1;
653e193acb3SGuenter Roeck 				break;
654e193acb3SGuenter Roeck 			case 4:
655e193acb3SGuenter Roeck 				reg = 2;
656e193acb3SGuenter Roeck 				break;
657e193acb3SGuenter Roeck 			case 8:
658e193acb3SGuenter Roeck 				reg = 3;
659e193acb3SGuenter Roeck 				break;
660e193acb3SGuenter Roeck 			default:
661e193acb3SGuenter Roeck 				ret = -EINVAL;
662e193acb3SGuenter Roeck 				goto error;
663e193acb3SGuenter Roeck 			}
664e193acb3SGuenter Roeck 			ret = i2c_smbus_write_byte_data(data->client,
665e193acb3SGuenter Roeck 							MAX6650_REG_COUNT, reg);
666e193acb3SGuenter Roeck 			if (ret)
667e193acb3SGuenter Roeck 				break;
668e193acb3SGuenter Roeck 			data->count = reg;
669e193acb3SGuenter Roeck 			break;
670e193acb3SGuenter Roeck 		case hwmon_fan_target:
671e193acb3SGuenter Roeck 			if (val < 0) {
672e193acb3SGuenter Roeck 				ret = -EINVAL;
673e193acb3SGuenter Roeck 				break;
674e193acb3SGuenter Roeck 			}
675e193acb3SGuenter Roeck 			ret = max6650_set_target(data, val);
676e193acb3SGuenter Roeck 			break;
677e193acb3SGuenter Roeck 		default:
678e193acb3SGuenter Roeck 			ret = -EOPNOTSUPP;
679e193acb3SGuenter Roeck 			break;
680e193acb3SGuenter Roeck 		}
681e193acb3SGuenter Roeck 		break;
682e193acb3SGuenter Roeck 	default:
683e193acb3SGuenter Roeck 		ret = -EOPNOTSUPP;
684e193acb3SGuenter Roeck 		break;
685e193acb3SGuenter Roeck 	}
686e193acb3SGuenter Roeck 
687e193acb3SGuenter Roeck error:
688e193acb3SGuenter Roeck 	mutex_unlock(&data->update_lock);
689e193acb3SGuenter Roeck 	return ret;
690e193acb3SGuenter Roeck }
691e193acb3SGuenter Roeck 
max6650_is_visible(const void * _data,enum hwmon_sensor_types type,u32 attr,int channel)692e193acb3SGuenter Roeck static umode_t max6650_is_visible(const void *_data,
693e193acb3SGuenter Roeck 				  enum hwmon_sensor_types type, u32 attr,
694e193acb3SGuenter Roeck 				  int channel)
695e193acb3SGuenter Roeck {
696e193acb3SGuenter Roeck 	const struct max6650_data *data = _data;
697e193acb3SGuenter Roeck 
698e193acb3SGuenter Roeck 	if (channel && (channel >= data->nr_fans || type != hwmon_fan))
699e193acb3SGuenter Roeck 		return 0;
700e193acb3SGuenter Roeck 
701e193acb3SGuenter Roeck 	switch (type) {
702e193acb3SGuenter Roeck 	case hwmon_fan:
703e193acb3SGuenter Roeck 		switch (attr) {
704e193acb3SGuenter Roeck 		case hwmon_fan_input:
705e193acb3SGuenter Roeck 			return 0444;
706e193acb3SGuenter Roeck 		case hwmon_fan_target:
707e193acb3SGuenter Roeck 		case hwmon_fan_div:
708e193acb3SGuenter Roeck 			return 0644;
709e193acb3SGuenter Roeck 		case hwmon_fan_min_alarm:
710e193acb3SGuenter Roeck 			if (data->alarm_en & MAX6650_ALRM_MIN)
711e193acb3SGuenter Roeck 				return 0444;
712e193acb3SGuenter Roeck 			break;
713e193acb3SGuenter Roeck 		case hwmon_fan_max_alarm:
714e193acb3SGuenter Roeck 			if (data->alarm_en & MAX6650_ALRM_MAX)
715e193acb3SGuenter Roeck 				return 0444;
716e193acb3SGuenter Roeck 			break;
717e193acb3SGuenter Roeck 		case hwmon_fan_fault:
718e193acb3SGuenter Roeck 			if (data->alarm_en & MAX6650_ALRM_TACH)
719e193acb3SGuenter Roeck 				return 0444;
720e193acb3SGuenter Roeck 			break;
721e193acb3SGuenter Roeck 		default:
722e193acb3SGuenter Roeck 			break;
723e193acb3SGuenter Roeck 		}
724e193acb3SGuenter Roeck 		break;
725e193acb3SGuenter Roeck 	case hwmon_pwm:
726e193acb3SGuenter Roeck 		switch (attr) {
727e193acb3SGuenter Roeck 		case hwmon_pwm_input:
728e193acb3SGuenter Roeck 		case hwmon_pwm_enable:
729e193acb3SGuenter Roeck 			return 0644;
730e193acb3SGuenter Roeck 		default:
731e193acb3SGuenter Roeck 			break;
732e193acb3SGuenter Roeck 		}
733e193acb3SGuenter Roeck 		break;
734e193acb3SGuenter Roeck 	default:
735e193acb3SGuenter Roeck 		break;
736e193acb3SGuenter Roeck 	}
737e193acb3SGuenter Roeck 	return 0;
738e193acb3SGuenter Roeck }
739e193acb3SGuenter Roeck 
7401c80f987SKrzysztof Kozlowski static const struct hwmon_channel_info * const max6650_info[] = {
741e193acb3SGuenter Roeck 	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_DIV |
742e193acb3SGuenter Roeck 			   HWMON_F_MIN_ALARM | HWMON_F_MAX_ALARM |
743e193acb3SGuenter Roeck 			   HWMON_F_FAULT,
744e193acb3SGuenter Roeck 			   HWMON_F_INPUT, HWMON_F_INPUT, HWMON_F_INPUT),
745e193acb3SGuenter Roeck 	HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
746e193acb3SGuenter Roeck 	NULL
747e193acb3SGuenter Roeck };
748e193acb3SGuenter Roeck 
749e193acb3SGuenter Roeck static const struct hwmon_ops max6650_hwmon_ops = {
750e193acb3SGuenter Roeck 	.read = max6650_read,
751e193acb3SGuenter Roeck 	.write = max6650_write,
752e193acb3SGuenter Roeck 	.is_visible = max6650_is_visible,
753e193acb3SGuenter Roeck };
754e193acb3SGuenter Roeck 
755e193acb3SGuenter Roeck static const struct hwmon_chip_info max6650_chip_info = {
756e193acb3SGuenter Roeck 	.ops = &max6650_hwmon_ops,
757e193acb3SGuenter Roeck 	.info = max6650_info,
758e193acb3SGuenter Roeck };
759e193acb3SGuenter Roeck 
76067487038SStephen Kitt static const struct i2c_device_id max6650_id[];
76167487038SStephen Kitt 
max6650_probe(struct i2c_client * client)76267487038SStephen Kitt static int max6650_probe(struct i2c_client *client)
763d20620deSHans-Juergen Koch {
7648e5e7dddSGuenter Roeck 	struct thermal_cooling_device *cooling_dev;
76571ba0f31SGuenter Roeck 	struct device *dev = &client->dev;
766a6cdeefeSMike Looijmans 	const struct of_device_id *of_id =
767a6cdeefeSMike Looijmans 		of_match_device(of_match_ptr(max6650_dt_match), dev);
7681577f94bSGuenter Roeck 	struct max6650_data *data;
76917eaa25cSGuenter Roeck 	struct device *hwmon_dev;
7701577f94bSGuenter Roeck 	int err;
771d20620deSHans-Juergen Koch 
77271ba0f31SGuenter Roeck 	data = devm_kzalloc(dev, sizeof(struct max6650_data), GFP_KERNEL);
7730b5e33b6SGuenter Roeck 	if (!data)
7741577f94bSGuenter Roeck 		return -ENOMEM;
7751577f94bSGuenter Roeck 
77617eaa25cSGuenter Roeck 	data->client = client;
7774f8d374bSJean-Francois Dagenais 	i2c_set_clientdata(client, data);
7781577f94bSGuenter Roeck 	mutex_init(&data->update_lock);
77967487038SStephen Kitt 	data->nr_fans = of_id ? (int)(uintptr_t)of_id->data :
78067487038SStephen Kitt 				i2c_match_id(max6650_id, client)->driver_data;
781d20620deSHans-Juergen Koch 
782703af960SGuenter Roeck 	/*
7831577f94bSGuenter Roeck 	 * Initialize the max6650 chip
784703af960SGuenter Roeck 	 */
78517eaa25cSGuenter Roeck 	err = max6650_init_client(data, client);
7861577f94bSGuenter Roeck 	if (err)
7871577f94bSGuenter Roeck 		return err;
78852b5226fSChristian Engelmayer 
789e193acb3SGuenter Roeck 	hwmon_dev = devm_hwmon_device_register_with_info(dev,
79017eaa25cSGuenter Roeck 							 client->name, data,
791e193acb3SGuenter Roeck 							 &max6650_chip_info,
792e193acb3SGuenter Roeck 							 max6650_groups);
7934f8d374bSJean-Francois Dagenais 	err = PTR_ERR_OR_ZERO(hwmon_dev);
7944f8d374bSJean-Francois Dagenais 	if (err)
7954f8d374bSJean-Francois Dagenais 		return err;
7964f8d374bSJean-Francois Dagenais 
7973253854dSArnd Bergmann 	if (IS_ENABLED(CONFIG_THERMAL)) {
7983253854dSArnd Bergmann 		cooling_dev = devm_thermal_of_cooling_device_register(dev,
7993253854dSArnd Bergmann 						dev->of_node, client->name,
8003253854dSArnd Bergmann 						data, &max6650_cooling_ops);
8018e5e7dddSGuenter Roeck 		if (IS_ERR(cooling_dev)) {
8028e5e7dddSGuenter Roeck 			dev_warn(dev, "thermal cooling device register failed: %ld\n",
8038e5e7dddSGuenter Roeck 				 PTR_ERR(cooling_dev));
8044f8d374bSJean-Francois Dagenais 		}
8053253854dSArnd Bergmann 	}
8063253854dSArnd Bergmann 
8074f8d374bSJean-Francois Dagenais 	return 0;
8081577f94bSGuenter Roeck }
8091577f94bSGuenter Roeck 
8101577f94bSGuenter Roeck static const struct i2c_device_id max6650_id[] = {
8111577f94bSGuenter Roeck 	{ "max6650", 1 },
8121577f94bSGuenter Roeck 	{ "max6651", 4 },
8131577f94bSGuenter Roeck 	{ }
8141577f94bSGuenter Roeck };
8151577f94bSGuenter Roeck MODULE_DEVICE_TABLE(i2c, max6650_id);
8161577f94bSGuenter Roeck 
8171577f94bSGuenter Roeck static struct i2c_driver max6650_driver = {
8181577f94bSGuenter Roeck 	.driver = {
8191577f94bSGuenter Roeck 		.name	= "max6650",
820a6cdeefeSMike Looijmans 		.of_match_table = of_match_ptr(max6650_dt_match),
8211577f94bSGuenter Roeck 	},
822*1975d167SUwe Kleine-König 	.probe		= max6650_probe,
8231577f94bSGuenter Roeck 	.id_table	= max6650_id,
8241577f94bSGuenter Roeck };
8251577f94bSGuenter Roeck 
826f0967eeaSAxel Lin module_i2c_driver(max6650_driver);
827d20620deSHans-Juergen Koch 
828d20620deSHans-Juergen Koch MODULE_AUTHOR("Hans J. Koch");
829d20620deSHans-Juergen Koch MODULE_DESCRIPTION("MAX6650 sensor driver");
830d20620deSHans-Juergen Koch MODULE_LICENSE("GPL");
831