sch5627.c (a54fe61639d9f3b6765fee32edda7cfceb6d705a) sch5627.c (10655bb6df25514e0ae8406637c3b4acbc812fe5)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/***************************************************************************
3 * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> *
4 * *
5 ***************************************************************************/
6
7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
9#include <linux/bits.h>
1// SPDX-License-Identifier: GPL-2.0-or-later
2/***************************************************************************
3 * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> *
4 * *
5 ***************************************************************************/
6
7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
9#include <linux/bits.h>
10#include <linux/minmax.h>
10#include <linux/module.h>
11#include <linux/mod_devicetable.h>
12#include <linux/pm.h>
13#include <linux/init.h>
14#include <linux/regmap.h>
15#include <linux/slab.h>
16#include <linux/jiffies.h>
17#include <linux/platform_device.h>

--- 54 unchanged lines hidden (view full) ---

72 10745, 3660, 9765, 10745, 3660 };
73static const char * const SCH5627_IN_LABELS[SCH5627_NO_IN] = {
74 "VCC", "VTT", "VBAT", "VTR", "V_IN" };
75
76struct sch5627_data {
77 struct regmap *regmap;
78 unsigned short addr;
79 u8 control;
11#include <linux/module.h>
12#include <linux/mod_devicetable.h>
13#include <linux/pm.h>
14#include <linux/init.h>
15#include <linux/regmap.h>
16#include <linux/slab.h>
17#include <linux/jiffies.h>
18#include <linux/platform_device.h>

--- 54 unchanged lines hidden (view full) ---

73 10745, 3660, 9765, 10745, 3660 };
74static const char * const SCH5627_IN_LABELS[SCH5627_NO_IN] = {
75 "VCC", "VTT", "VBAT", "VTR", "V_IN" };
76
77struct sch5627_data {
78 struct regmap *regmap;
79 unsigned short addr;
80 u8 control;
80 u8 temp_max[SCH5627_NO_TEMPS];
81 u8 temp_crit[SCH5627_NO_TEMPS];
82 u16 fan_min[SCH5627_NO_FANS];
83
84 struct mutex update_lock;
85 unsigned long last_battery; /* In jiffies */
86 char temp_valid; /* !=0 if following fields are valid */
87 char fan_valid;
88 char in_valid;
89 unsigned long temp_last_updated; /* In jiffies */
90 unsigned long fan_last_updated;
91 unsigned long in_last_updated;
92 u16 temp[SCH5627_NO_TEMPS];
93 u16 fan[SCH5627_NO_FANS];
94 u16 in[SCH5627_NO_IN];
95};
96
97static const struct regmap_range sch5627_tunables_ranges[] = {
81
82 struct mutex update_lock;
83 unsigned long last_battery; /* In jiffies */
84 char temp_valid; /* !=0 if following fields are valid */
85 char fan_valid;
86 char in_valid;
87 unsigned long temp_last_updated; /* In jiffies */
88 unsigned long fan_last_updated;
89 unsigned long in_last_updated;
90 u16 temp[SCH5627_NO_TEMPS];
91 u16 fan[SCH5627_NO_FANS];
92 u16 in[SCH5627_NO_IN];
93};
94
95static const struct regmap_range sch5627_tunables_ranges[] = {
96 regmap_reg_range(0x57, 0x57),
97 regmap_reg_range(0x59, 0x59),
98 regmap_reg_range(0x5B, 0x5B),
99 regmap_reg_range(0x5D, 0x5D),
100 regmap_reg_range(0x5F, 0x5F),
101 regmap_reg_range(0x61, 0x69),
102 regmap_reg_range(0x96, 0x9B),
98 regmap_reg_range(0xA0, 0xA3),
103 regmap_reg_range(0xA0, 0xA3),
104 regmap_reg_range(0x184, 0x184),
105 regmap_reg_range(0x186, 0x186),
106 regmap_reg_range(0x1A8, 0x1A9),
99};
100
101static const struct regmap_access_table sch5627_tunables_table = {
102 .yes_ranges = sch5627_tunables_ranges,
103 .n_yes_ranges = ARRAY_SIZE(sch5627_tunables_ranges),
104};
105
106static const struct regmap_config sch5627_regmap_config = {

--- 88 unchanged lines hidden (view full) ---

195 data->in_last_updated = jiffies;
196 data->in_valid = 1;
197 }
198abort:
199 mutex_unlock(&data->update_lock);
200 return ret;
201}
202
107};
108
109static const struct regmap_access_table sch5627_tunables_table = {
110 .yes_ranges = sch5627_tunables_ranges,
111 .n_yes_ranges = ARRAY_SIZE(sch5627_tunables_ranges),
112};
113
114static const struct regmap_config sch5627_regmap_config = {

--- 88 unchanged lines hidden (view full) ---

203 data->in_last_updated = jiffies;
204 data->in_valid = 1;
205 }
206abort:
207 mutex_unlock(&data->update_lock);
208 return ret;
209}
210
203static int sch5627_read_limits(struct sch5627_data *data)
204{
205 int i, val;
206
207 for (i = 0; i < SCH5627_NO_TEMPS; i++) {
208 /*
209 * Note what SMSC calls ABS, is what lm_sensors calls max
210 * (aka high), and HIGH is what lm_sensors calls crit.
211 */
212 val = sch56xx_read_virtual_reg(data->addr,
213 SCH5627_REG_TEMP_ABS[i]);
214 if (val < 0)
215 return val;
216 data->temp_max[i] = val;
217
218 val = sch56xx_read_virtual_reg(data->addr,
219 SCH5627_REG_TEMP_HIGH[i]);
220 if (val < 0)
221 return val;
222 data->temp_crit[i] = val;
223 }
224 for (i = 0; i < SCH5627_NO_FANS; i++) {
225 val = sch56xx_read_virtual_reg16(data->addr,
226 SCH5627_REG_FAN_MIN[i]);
227 if (val < 0)
228 return val;
229 data->fan_min[i] = val;
230 }
231
232 return 0;
233}
234
235static int reg_to_temp(u16 reg)
236{
237 return (reg * 625) / 10 - 64000;
238}
239
240static int reg_to_temp_limit(u8 reg)
241{
242 return (reg - 64) * 1000;

--- 4 unchanged lines hidden (view full) ---

247 if (reg == 0)
248 return -EIO;
249 if (reg == 0xffff)
250 return 0;
251
252 return 5400540 / reg;
253}
254
211static int reg_to_temp(u16 reg)
212{
213 return (reg * 625) / 10 - 64000;
214}
215
216static int reg_to_temp_limit(u8 reg)
217{
218 return (reg - 64) * 1000;

--- 4 unchanged lines hidden (view full) ---

223 if (reg == 0)
224 return -EIO;
225 if (reg == 0xffff)
226 return 0;
227
228 return 5400540 / reg;
229}
230
231static u8 sch5627_temp_limit_to_reg(long value)
232{
233 long limit = (value / 1000) + 64;
234
235 return clamp_val(limit, 0, U8_MAX);
236}
237
238static u16 sch5627_rpm_to_reg(long value)
239{
240 long pulses;
241
242 if (value <= 0)
243 return U16_MAX - 1;
244
245 pulses = 5400540 / value;
246
247 return clamp_val(pulses, 1, U16_MAX - 1);
248}
249
255static umode_t sch5627_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
256 int channel)
257{
258 const struct sch5627_data *data = drvdata;
259
260 /* Once the lock bit is set, the virtual registers become read-only
261 * until the next power cycle.
262 */
263 if (data->control & SCH5627_CTRL_LOCK)
264 return 0444;
265
250static umode_t sch5627_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
251 int channel)
252{
253 const struct sch5627_data *data = drvdata;
254
255 /* Once the lock bit is set, the virtual registers become read-only
256 * until the next power cycle.
257 */
258 if (data->control & SCH5627_CTRL_LOCK)
259 return 0444;
260
266 if (type == hwmon_pwm && attr == hwmon_pwm_auto_channels_temp)
267 return 0644;
261 switch (type) {
262 case hwmon_temp:
263 switch (attr) {
264 case hwmon_temp_max:
265 case hwmon_temp_crit:
266 return 0644;
267 default:
268 break;
269 }
270 break;
271 case hwmon_fan:
272 switch (attr) {
273 case hwmon_fan_min:
274 return 0644;
275 default:
276 break;
277 }
278 break;
279 case hwmon_pwm:
280 switch (attr) {
281 case hwmon_pwm_auto_channels_temp:
282 return 0644;
283 default:
284 break;
285 }
286 break;
287 default:
288 break;
289 }
268
269 return 0444;
270}
271
272static int sch5627_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
273 long *val)
274{
275 struct sch5627_data *data = dev_get_drvdata(dev);
276 int ret, value;
277
278 switch (type) {
279 case hwmon_temp:
290
291 return 0444;
292}
293
294static int sch5627_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
295 long *val)
296{
297 struct sch5627_data *data = dev_get_drvdata(dev);
298 int ret, value;
299
300 switch (type) {
301 case hwmon_temp:
280 ret = sch5627_update_temp(data);
281 if (ret < 0)
282 return ret;
283 switch (attr) {
284 case hwmon_temp_input:
302 switch (attr) {
303 case hwmon_temp_input:
304 ret = sch5627_update_temp(data);
305 if (ret < 0)
306 return ret;
307
285 *val = reg_to_temp(data->temp[channel]);
286 return 0;
287 case hwmon_temp_max:
308 *val = reg_to_temp(data->temp[channel]);
309 return 0;
310 case hwmon_temp_max:
288 *val = reg_to_temp_limit(data->temp_max[channel]);
311 ret = regmap_read(data->regmap, SCH5627_REG_TEMP_ABS[channel], &value);
312 if (ret < 0)
313 return ret;
314
315 *val = reg_to_temp_limit((u8)value);
289 return 0;
290 case hwmon_temp_crit:
316 return 0;
317 case hwmon_temp_crit:
291 *val = reg_to_temp_limit(data->temp_crit[channel]);
318 ret = regmap_read(data->regmap, SCH5627_REG_TEMP_HIGH[channel], &value);
319 if (ret < 0)
320 return ret;
321
322 *val = reg_to_temp_limit((u8)value);
292 return 0;
293 case hwmon_temp_fault:
323 return 0;
324 case hwmon_temp_fault:
325 ret = sch5627_update_temp(data);
326 if (ret < 0)
327 return ret;
328
294 *val = (data->temp[channel] == 0);
295 return 0;
296 default:
297 break;
298 }
299 break;
300 case hwmon_fan:
329 *val = (data->temp[channel] == 0);
330 return 0;
331 default:
332 break;
333 }
334 break;
335 case hwmon_fan:
301 ret = sch5627_update_fan(data);
302 if (ret < 0)
303 return ret;
304 switch (attr) {
305 case hwmon_fan_input:
336 switch (attr) {
337 case hwmon_fan_input:
338 ret = sch5627_update_fan(data);
339 if (ret < 0)
340 return ret;
341
306 ret = reg_to_rpm(data->fan[channel]);
307 if (ret < 0)
308 return ret;
342 ret = reg_to_rpm(data->fan[channel]);
343 if (ret < 0)
344 return ret;
345
309 *val = ret;
310 return 0;
311 case hwmon_fan_min:
346 *val = ret;
347 return 0;
348 case hwmon_fan_min:
312 ret = reg_to_rpm(data->fan_min[channel]);
349 ret = sch56xx_regmap_read16(data->regmap, SCH5627_REG_FAN_MIN[channel],
350 &value);
313 if (ret < 0)
314 return ret;
351 if (ret < 0)
352 return ret;
353
354 ret = reg_to_rpm((u16)value);
355 if (ret < 0)
356 return ret;
357
315 *val = ret;
316 return 0;
317 case hwmon_fan_fault:
358 *val = ret;
359 return 0;
360 case hwmon_fan_fault:
361 ret = sch5627_update_fan(data);
362 if (ret < 0)
363 return ret;
364
318 *val = (data->fan[channel] == 0xffff);
319 return 0;
320 default:
321 break;
322 }
323 break;
324 case hwmon_pwm:
325 switch (attr) {

--- 47 unchanged lines hidden (view full) ---

373
374 return -EOPNOTSUPP;
375}
376
377static int sch5627_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
378 long val)
379{
380 struct sch5627_data *data = dev_get_drvdata(dev);
365 *val = (data->fan[channel] == 0xffff);
366 return 0;
367 default:
368 break;
369 }
370 break;
371 case hwmon_pwm:
372 switch (attr) {

--- 47 unchanged lines hidden (view full) ---

420
421 return -EOPNOTSUPP;
422}
423
424static int sch5627_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
425 long val)
426{
427 struct sch5627_data *data = dev_get_drvdata(dev);
428 u16 fan;
429 u8 temp;
381
382 switch (type) {
430
431 switch (type) {
432 case hwmon_temp:
433 temp = sch5627_temp_limit_to_reg(val);
434
435 switch (attr) {
436 case hwmon_temp_max:
437 return regmap_write(data->regmap, SCH5627_REG_TEMP_ABS[channel], temp);
438 case hwmon_temp_crit:
439 return regmap_write(data->regmap, SCH5627_REG_TEMP_HIGH[channel], temp);
440 default:
441 break;
442 }
443 break;
444 case hwmon_fan:
445 switch (attr) {
446 case hwmon_fan_min:
447 fan = sch5627_rpm_to_reg(val);
448
449 return sch56xx_regmap_write16(data->regmap, SCH5627_REG_FAN_MIN[channel],
450 fan);
451 default:
452 break;
453 }
454 break;
383 case hwmon_pwm:
384 switch (attr) {
385 case hwmon_pwm_auto_channels_temp:
386 /* registers are 8 bit wide */
387 if (val > U8_MAX || val < 0)
388 return -EINVAL;
389
390 return regmap_write(data->regmap, SCH5627_REG_PWM_MAP[channel], val);

--- 53 unchanged lines hidden (view full) ---

444 .ops = &sch5627_ops,
445 .info = sch5627_info,
446};
447
448static int sch5627_probe(struct platform_device *pdev)
449{
450 struct sch5627_data *data;
451 struct device *hwmon_dev;
455 case hwmon_pwm:
456 switch (attr) {
457 case hwmon_pwm_auto_channels_temp:
458 /* registers are 8 bit wide */
459 if (val > U8_MAX || val < 0)
460 return -EINVAL;
461
462 return regmap_write(data->regmap, SCH5627_REG_PWM_MAP[channel], val);

--- 53 unchanged lines hidden (view full) ---

516 .ops = &sch5627_ops,
517 .info = sch5627_info,
518};
519
520static int sch5627_probe(struct platform_device *pdev)
521{
522 struct sch5627_data *data;
523 struct device *hwmon_dev;
452 int err, build_code, build_id, hwmon_rev, val;
524 int build_code, build_id, hwmon_rev, val;
453
454 data = devm_kzalloc(&pdev->dev, sizeof(struct sch5627_data),
455 GFP_KERNEL);
456 if (!data)
457 return -ENOMEM;
458
459 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
460 mutex_init(&data->update_lock);

--- 59 unchanged lines hidden (view full) ---

520 if (IS_ERR(data->regmap))
521 return PTR_ERR(data->regmap);
522
523 /* Trigger a Vbat voltage measurement, so that we get a valid reading
524 the first time we read Vbat */
525 sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | SCH5627_CTRL_VBAT);
526 data->last_battery = jiffies;
527
525
526 data = devm_kzalloc(&pdev->dev, sizeof(struct sch5627_data),
527 GFP_KERNEL);
528 if (!data)
529 return -ENOMEM;
530
531 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
532 mutex_init(&data->update_lock);

--- 59 unchanged lines hidden (view full) ---

592 if (IS_ERR(data->regmap))
593 return PTR_ERR(data->regmap);
594
595 /* Trigger a Vbat voltage measurement, so that we get a valid reading
596 the first time we read Vbat */
597 sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | SCH5627_CTRL_VBAT);
598 data->last_battery = jiffies;
599
528 /*
529 * Read limits, we do this only once as reading a register on
530 * the sch5627 is quite expensive (and they don't change).
531 */
532 err = sch5627_read_limits(data);
533 if (err)
534 return err;
535
536 pr_info("found %s chip at %#hx\n", DEVNAME, data->addr);
537 pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n",
538 build_code, build_id, hwmon_rev);
539
540 hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, DEVNAME, data,
541 &sch5627_chip_info, NULL);
542 if (IS_ERR(hwmon_dev))
543 return PTR_ERR(hwmon_dev);

--- 55 unchanged lines hidden ---
600 pr_info("found %s chip at %#hx\n", DEVNAME, data->addr);
601 pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n",
602 build_code, build_id, hwmon_rev);
603
604 hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, DEVNAME, data,
605 &sch5627_chip_info, NULL);
606 if (IS_ERR(hwmon_dev))
607 return PTR_ERR(hwmon_dev);

--- 55 unchanged lines hidden ---