Skip to content

Commit 4b6358e

Browse files
bobisnoobgroeck
authored andcommitted
hwmon: (lm75) Add AMS AS6200 temperature sensor
as6200 is a temperature sensor with 0.0625°C resolution and a range between -40°C to 125°C. By default, the driver configures as6200 as following: - Converstion rate: 8 Hz - Conversion mode: continuous - Consecutive fault counts: 4 samples - Alert state: high polarity - Alert mode: comparator mode Interrupt is supported for the alert pin. Signed-off-by: Abdel Alkuor <[email protected]> Link: https://lore.kernel.org/r/d1686678991bf8ee0d00cb08ca046798f37ca4b3.1703127334.git.alkuor@gmail.com Signed-off-by: Guenter Roeck <[email protected]>
1 parent de9c603 commit 4b6358e

File tree

2 files changed

+104
-14
lines changed

2 files changed

+104
-14
lines changed

Documentation/hwmon/lm75.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ Supported chips:
133133

134134
https://www.nxp.com/docs/en/data-sheet/PCT2075.pdf
135135

136+
* AMS OSRAM AS6200
137+
138+
Prefix: 'as6200'
139+
140+
Addresses scanned: none
141+
142+
Datasheet: Publicly available at the AMS website
143+
144+
https://ams.com/documents/20143/36005/AS6200_DS000449_4-00.pdf
145+
136146
Author: Frodo Looijaard <[email protected]>
137147

138148
Description

drivers/hwmon/lm75.c

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <linux/module.h>
99
#include <linux/init.h>
10+
#include <linux/interrupt.h>
1011
#include <linux/slab.h>
1112
#include <linux/jiffies.h>
1213
#include <linux/i2c.h>
@@ -24,6 +25,7 @@
2425

2526
enum lm75_type { /* keep sorted in alphabetical order */
2627
adt75,
28+
as6200,
2729
at30ts74,
2830
ds1775,
2931
ds75,
@@ -54,6 +56,7 @@ enum lm75_type { /* keep sorted in alphabetical order */
5456

5557
/**
5658
* struct lm75_params - lm75 configuration parameters.
59+
* @config_reg_16bits: Configure register size is 2 bytes.
5760
* @set_mask: Bits to set in configuration register when configuring
5861
* the chip.
5962
* @clr_mask: Bits to clear in configuration register when configuring
@@ -74,17 +77,20 @@ enum lm75_type { /* keep sorted in alphabetical order */
7477
* @sample_times: All the possible sample times to be set. Mandatory if
7578
* num_sample_times is larger than 1. If set, number of
7679
* entries must match num_sample_times.
80+
* @alarm: Alarm bit is supported.
7781
*/
7882

7983
struct lm75_params {
80-
u8 set_mask;
81-
u8 clr_mask;
84+
bool config_reg_16bits;
85+
u16 set_mask;
86+
u16 clr_mask;
8287
u8 default_resolution;
8388
u8 resolution_limits;
8489
const u8 *resolutions;
8590
unsigned int default_sample_time;
8691
u8 num_sample_times;
8792
const unsigned int *sample_times;
93+
bool alarm;
8894
};
8995

9096
/* Addresses scanned */
@@ -103,8 +109,8 @@ struct lm75_data {
103109
struct i2c_client *client;
104110
struct regmap *regmap;
105111
struct regulator *vs;
106-
u8 orig_conf;
107-
u8 current_conf;
112+
u16 orig_conf;
113+
u16 current_conf;
108114
u8 resolution; /* In bits, 9 to 16 */
109115
unsigned int sample_time; /* In ms */
110116
enum lm75_type kind;
@@ -127,6 +133,15 @@ static const struct lm75_params device_params[] = {
127133
.default_resolution = 12,
128134
.default_sample_time = MSEC_PER_SEC / 10,
129135
},
136+
[as6200] = {
137+
.config_reg_16bits = true,
138+
.set_mask = 0x94C0, /* 8 sample/s, 4 CF, positive polarity */
139+
.default_resolution = 12,
140+
.default_sample_time = 125,
141+
.num_sample_times = 4,
142+
.sample_times = (unsigned int []){ 125, 250, 1000, 4000 },
143+
.alarm = true,
144+
},
130145
[at30ts74] = {
131146
.set_mask = 3 << 5, /* 12-bit mode*/
132147
.default_resolution = 12,
@@ -316,27 +331,51 @@ static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
316331
return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
317332
}
318333

319-
static int lm75_write_config(struct lm75_data *data, u8 set_mask,
320-
u8 clr_mask)
334+
static int lm75_write_config(struct lm75_data *data, u16 set_mask,
335+
u16 clr_mask)
321336
{
322-
u8 value;
337+
unsigned int value;
323338

324-
clr_mask |= LM75_SHUTDOWN;
339+
clr_mask |= LM75_SHUTDOWN << (8 * data->params->config_reg_16bits);
325340
value = data->current_conf & ~clr_mask;
326341
value |= set_mask;
327342

328343
if (data->current_conf != value) {
329344
s32 err;
330-
331-
err = i2c_smbus_write_byte_data(data->client, LM75_REG_CONF,
332-
value);
345+
if (data->params->config_reg_16bits)
346+
err = regmap_write(data->regmap, LM75_REG_CONF, value);
347+
else
348+
err = i2c_smbus_write_byte_data(data->client,
349+
LM75_REG_CONF,
350+
value);
333351
if (err)
334352
return err;
335353
data->current_conf = value;
336354
}
337355
return 0;
338356
}
339357

358+
static int lm75_read_config(struct lm75_data *data)
359+
{
360+
int ret;
361+
unsigned int status;
362+
363+
if (data->params->config_reg_16bits) {
364+
ret = regmap_read(data->regmap, LM75_REG_CONF, &status);
365+
return ret ? ret : status;
366+
}
367+
368+
return i2c_smbus_read_byte_data(data->client, LM75_REG_CONF);
369+
}
370+
371+
static irqreturn_t lm75_alarm_handler(int irq, void *private)
372+
{
373+
struct device *hwmon_dev = private;
374+
375+
hwmon_notify_event(hwmon_dev, hwmon_temp, hwmon_temp_alarm, 0);
376+
return IRQ_HANDLED;
377+
}
378+
340379
static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
341380
u32 attr, int channel, long *val)
342381
{
@@ -365,14 +404,27 @@ static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
365404
case hwmon_temp_max_hyst:
366405
reg = LM75_REG_HYST;
367406
break;
407+
case hwmon_temp_alarm:
408+
reg = LM75_REG_CONF;
409+
break;
368410
default:
369411
return -EINVAL;
370412
}
371413
err = regmap_read(data->regmap, reg, &regval);
372414
if (err < 0)
373415
return err;
374416

375-
*val = lm75_reg_to_mc(regval, data->resolution);
417+
if (attr == hwmon_temp_alarm) {
418+
switch (data->kind) {
419+
case as6200:
420+
*val = (regval >> 5) & 0x1;
421+
break;
422+
default:
423+
return -EINVAL;
424+
}
425+
} else {
426+
*val = lm75_reg_to_mc(regval, data->resolution);
427+
}
376428
break;
377429
default:
378430
return -EINVAL;
@@ -435,6 +487,7 @@ static int lm75_update_interval(struct device *dev, long val)
435487
data->resolution = data->params->resolutions[index];
436488
break;
437489
case tmp112:
490+
case as6200:
438491
err = regmap_read(data->regmap, LM75_REG_CONF, &reg);
439492
if (err < 0)
440493
return err;
@@ -502,6 +555,10 @@ static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type,
502555
case hwmon_temp_max:
503556
case hwmon_temp_max_hyst:
504557
return 0644;
558+
case hwmon_temp_alarm:
559+
if (config_data->params->alarm)
560+
return 0444;
561+
break;
505562
}
506563
break;
507564
default:
@@ -514,7 +571,8 @@ static const struct hwmon_channel_info * const lm75_info[] = {
514571
HWMON_CHANNEL_INFO(chip,
515572
HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL),
516573
HWMON_CHANNEL_INFO(temp,
517-
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST),
574+
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
575+
HWMON_T_ALARM),
518576
NULL
519577
};
520578

@@ -622,7 +680,7 @@ static int lm75_probe(struct i2c_client *client)
622680
return err;
623681

624682
/* Cache original configuration */
625-
status = i2c_smbus_read_byte_data(client, LM75_REG_CONF);
683+
status = lm75_read_config(data);
626684
if (status < 0) {
627685
dev_dbg(dev, "Can't read config? %d\n", status);
628686
return status;
@@ -645,13 +703,31 @@ static int lm75_probe(struct i2c_client *client)
645703
if (IS_ERR(hwmon_dev))
646704
return PTR_ERR(hwmon_dev);
647705

706+
if (client->irq) {
707+
if (data->params->alarm) {
708+
err = devm_request_threaded_irq(dev,
709+
client->irq,
710+
NULL,
711+
&lm75_alarm_handler,
712+
IRQF_ONESHOT,
713+
client->name,
714+
hwmon_dev);
715+
if (err)
716+
return err;
717+
} else {
718+
/* alarm is only supported for chips with alarm bit */
719+
dev_err(dev, "alarm interrupt is not supported\n");
720+
}
721+
}
722+
648723
dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name);
649724

650725
return 0;
651726
}
652727

653728
static const struct i2c_device_id lm75_ids[] = {
654729
{ "adt75", adt75, },
730+
{ "as6200", as6200, },
655731
{ "at30ts74", at30ts74, },
656732
{ "ds1775", ds1775, },
657733
{ "ds75", ds75, },
@@ -688,6 +764,10 @@ static const struct of_device_id __maybe_unused lm75_of_match[] = {
688764
.compatible = "adi,adt75",
689765
.data = (void *)adt75
690766
},
767+
{
768+
.compatible = "ams,as6200",
769+
.data = (void *)as6200
770+
},
691771
{
692772
.compatible = "atmel,at30ts74",
693773
.data = (void *)at30ts74

0 commit comments

Comments
 (0)