2929
3030#include <linux/err.h>
3131#include <linux/hwmon.h>
32- #include <linux/hwmon-sysfs.h>
3332#include <linux/i2c.h>
3433#include <linux/init.h>
3534#include <linux/module.h>
@@ -76,169 +75,216 @@ static inline u8 ALARMS_FROM_REG(s16 reg)
7675 return reg & 0x0007 ;
7776}
7877
79- enum temp_index {
80- t_input ,
81- t_crit ,
82- t_min ,
83- t_max ,
84- t_num_regs
85- };
86-
87- static const u8 lm92_regs [t_num_regs ] = {
88- [t_input ] = LM92_REG_TEMP ,
89- [t_crit ] = LM92_REG_TEMP_CRIT ,
90- [t_min ] = LM92_REG_TEMP_LOW ,
91- [t_max ] = LM92_REG_TEMP_HIGH ,
92- };
93-
9478/* Client data (each client gets its own) */
9579struct lm92_data {
9680 struct regmap * regmap ;
9781 struct mutex update_lock ;
9882 int resolution ;
9983};
10084
101- /*
102- * Sysfs attributes and callback functions
103- */
104-
105- static ssize_t temp_show (struct device * dev , struct device_attribute * devattr ,
106- char * buf )
85+ static int lm92_temp_read (struct lm92_data * data , u32 attr , int channel , long * val )
10786{
108- struct sensor_device_attribute * attr = to_sensor_dev_attr (devattr );
109- struct lm92_data * data = dev_get_drvdata (dev );
110- u32 temp ;
111- int err ;
112-
113- err = regmap_read (data -> regmap , lm92_regs [attr -> index ], & temp );
114- if (err )
115- return err ;
116-
117- return sprintf (buf , "%d\n" , TEMP_FROM_REG (temp ));
118- }
119-
120- static ssize_t temp_store (struct device * dev ,
121- struct device_attribute * devattr , const char * buf ,
122- size_t count )
123- {
124- struct sensor_device_attribute * attr = to_sensor_dev_attr (devattr );
125- struct lm92_data * data = dev_get_drvdata (dev );
87+ int reg = -1 , hyst_reg = -1 , alarm_bit = 0 ;
12688 struct regmap * regmap = data -> regmap ;
127- int nr = attr -> index ;
128- long val ;
129- int err ;
130-
131- err = kstrtol (buf , 10 , & val );
132- if (err )
133- return err ;
89+ u32 temp ;
90+ int ret ;
13491
135- err = regmap_write (regmap , lm92_regs [nr ], TEMP_TO_REG (val , data -> resolution ));
136- if (err )
137- return err ;
138- return count ;
92+ switch (attr ) {
93+ case hwmon_temp_input :
94+ reg = LM92_REG_TEMP ;
95+ break ;
96+ case hwmon_temp_min :
97+ reg = LM92_REG_TEMP_LOW ;
98+ break ;
99+ case hwmon_temp_max :
100+ reg = LM92_REG_TEMP_HIGH ;
101+ break ;
102+ case hwmon_temp_crit :
103+ reg = LM92_REG_TEMP_CRIT ;
104+ break ;
105+ case hwmon_temp_min_hyst :
106+ hyst_reg = LM92_REG_TEMP_LOW ;
107+ break ;
108+ case hwmon_temp_max_hyst :
109+ hyst_reg = LM92_REG_TEMP_HIGH ;
110+ break ;
111+ case hwmon_temp_crit_hyst :
112+ hyst_reg = LM92_REG_TEMP_CRIT ;
113+ break ;
114+ case hwmon_temp_min_alarm :
115+ alarm_bit = 0 ;
116+ break ;
117+ case hwmon_temp_max_alarm :
118+ alarm_bit = 1 ;
119+ break ;
120+ case hwmon_temp_crit_alarm :
121+ alarm_bit = 2 ;
122+ break ;
123+ default :
124+ return - EOPNOTSUPP ;
125+ }
126+ if (reg >= 0 ) {
127+ ret = regmap_read (regmap , reg , & temp );
128+ if (ret < 0 )
129+ return ret ;
130+ * val = TEMP_FROM_REG (temp );
131+ } else if (hyst_reg >= 0 ) {
132+ u32 regs [2 ] = { hyst_reg , LM92_REG_TEMP_HYST };
133+ u16 regvals [2 ];
134+
135+ ret = regmap_multi_reg_read (regmap , regs , regvals , 2 );
136+ if (ret )
137+ return ret ;
138+ if (attr == hwmon_temp_min_hyst )
139+ * val = TEMP_FROM_REG (regvals [0 ]) + TEMP_FROM_REG (regvals [1 ]);
140+ else
141+ * val = TEMP_FROM_REG (regvals [0 ]) - TEMP_FROM_REG (regvals [1 ]);
142+ } else {
143+ ret = regmap_read (regmap , LM92_REG_TEMP , & temp );
144+ if (ret )
145+ return ret ;
146+ * val = !!(temp & BIT (alarm_bit ));
147+ }
148+ return 0 ;
139149}
140150
141- static ssize_t temp_hyst_show (struct device * dev ,
142- struct device_attribute * devattr , char * buf )
151+ static int lm92_chip_read (struct lm92_data * data , u32 attr , long * val )
143152{
144- struct sensor_device_attribute * attr = to_sensor_dev_attr (devattr );
145- u32 regs [2 ] = { lm92_regs [attr -> index ], LM92_REG_TEMP_HYST };
146- struct lm92_data * data = dev_get_drvdata (dev );
147- u16 regvals [2 ];
148- int err ;
149-
150- err = regmap_multi_reg_read (data -> regmap , regs , regvals , 2 );
151- if (err )
152- return err ;
153+ u32 temp ;
154+ int ret ;
153155
154- return sprintf (buf , "%d\n" ,
155- TEMP_FROM_REG (regvals [0 ]) - TEMP_FROM_REG (regvals [1 ]));
156+ switch (attr ) {
157+ case hwmon_chip_alarms :
158+ ret = regmap_read (data -> regmap , LM92_REG_TEMP , & temp );
159+ if (ret )
160+ return ret ;
161+ * val = ALARMS_FROM_REG (temp );
162+ break ;
163+ default :
164+ return - EOPNOTSUPP ;
165+ }
166+ return 0 ;
156167}
157168
158- static ssize_t temp1_min_hyst_show (struct device * dev ,
159- struct device_attribute * attr , char * buf )
169+ static int lm92_read (struct device * dev , enum hwmon_sensor_types type , u32 attr ,
170+ int channel , long * val )
160171{
161- static u32 regs [2 ] = { LM92_REG_TEMP_LOW , LM92_REG_TEMP_HYST };
162172 struct lm92_data * data = dev_get_drvdata (dev );
163- u16 regvals [2 ];
164- int err ;
165-
166- err = regmap_multi_reg_read (data -> regmap , regs , regvals , 2 );
167- if (err )
168- return err ;
169173
170- return sprintf (buf , "%d\n" ,
171- TEMP_FROM_REG (regvals [0 ]) + TEMP_FROM_REG (regvals [1 ]));
174+ switch (type ) {
175+ case hwmon_chip :
176+ return lm92_chip_read (data , attr , val );
177+ case hwmon_temp :
178+ return lm92_temp_read (data , attr , channel , val );
179+ default :
180+ return - EOPNOTSUPP ;
181+ }
172182}
173183
174- static ssize_t temp_hyst_store (struct device * dev ,
175- struct device_attribute * devattr ,
176- const char * buf , size_t count )
184+ static int lm92_temp_write (struct lm92_data * data , u32 attr , long val )
177185{
178- struct lm92_data * data = dev_get_drvdata (dev );
179186 struct regmap * regmap = data -> regmap ;
187+ int reg , err ;
180188 u32 temp ;
181- long val ;
182- int err ;
183-
184- err = kstrtol (buf , 10 , & val );
185- if (err )
186- return err ;
187189
188- val = clamp_val (val , -120000 , 220000 );
189- mutex_lock (& data -> update_lock );
190- err = regmap_read (regmap , LM92_REG_TEMP_CRIT , & temp );
191- if (err )
192- goto unlock ;
193- val = TEMP_TO_REG (TEMP_FROM_REG (temp ) - val , data -> resolution );
194- err = regmap_write (regmap , LM92_REG_TEMP_HYST , val );
190+ switch (attr ) {
191+ case hwmon_temp_min :
192+ reg = LM92_REG_TEMP_LOW ;
193+ break ;
194+ case hwmon_temp_max :
195+ reg = LM92_REG_TEMP_HIGH ;
196+ break ;
197+ case hwmon_temp_crit :
198+ reg = LM92_REG_TEMP_CRIT ;
199+ break ;
200+ case hwmon_temp_crit_hyst :
201+ val = clamp_val (val , -120000 , 220000 );
202+ mutex_lock (& data -> update_lock );
203+ err = regmap_read (regmap , LM92_REG_TEMP_CRIT , & temp );
204+ if (err )
205+ goto unlock ;
206+ val = TEMP_TO_REG (TEMP_FROM_REG (temp ) - val , data -> resolution );
207+ err = regmap_write (regmap , LM92_REG_TEMP_HYST , val );
195208unlock :
196- mutex_unlock (& data -> update_lock );
197- if (err )
209+ mutex_unlock (& data -> update_lock );
198210 return err ;
199- return count ;
211+ default :
212+ return - EOPNOTSUPP ;
213+ }
214+ return regmap_write (regmap , reg , TEMP_TO_REG (val , data -> resolution ));
200215}
201216
202- static ssize_t alarms_show (struct device * dev , struct device_attribute * attr ,
203- char * buf )
217+ static int lm92_write (struct device * dev , enum hwmon_sensor_types type ,
218+ u32 attr , int channel , long val )
204219{
205220 struct lm92_data * data = dev_get_drvdata (dev );
206- u32 temp ;
207- int err ;
208-
209- err = regmap_read (data -> regmap , LM92_REG_TEMP , & temp );
210- if (err )
211- return err ;
212221
213- return sprintf (buf , "%d\n" , ALARMS_FROM_REG (temp ));
222+ switch (type ) {
223+ case hwmon_temp :
224+ return lm92_temp_write (data , attr , val );
225+ default :
226+ return - EOPNOTSUPP ;
227+ }
214228}
215229
216- static ssize_t alarm_show ( struct device * dev , struct device_attribute * attr ,
217- char * buf )
230+ static umode_t lm92_is_visible ( const void * _data , enum hwmon_sensor_types type ,
231+ u32 attr , int channel )
218232{
219- struct lm92_data * data = dev_get_drvdata (dev );
220- int bitnr = to_sensor_dev_attr (attr )-> index ;
221- u32 temp ;
222- int err ;
233+ switch (type ) {
234+ case hwmon_chip :
235+ switch (attr ) {
236+ case hwmon_chip_alarms :
237+ return 0444 ;
238+ default :
239+ break ;
240+ }
241+ break ;
242+ case hwmon_temp :
243+ switch (attr ) {
244+ case hwmon_temp_min :
245+ case hwmon_temp_max :
246+ case hwmon_temp_crit :
247+ case hwmon_temp_crit_hyst :
248+ return 0644 ;
249+ case hwmon_temp_input :
250+ case hwmon_temp_min_hyst :
251+ case hwmon_temp_max_hyst :
252+ case hwmon_temp_min_alarm :
253+ case hwmon_temp_max_alarm :
254+ case hwmon_temp_crit_alarm :
255+ return 0444 ;
256+ default :
257+ break ;
258+ }
259+ break ;
260+ default :
261+ break ;
262+ }
263+ return 0 ;
264+ }
223265
224- err = regmap_read (data -> regmap , LM92_REG_TEMP , & temp );
225- if (err )
226- return err ;
266+ static const struct hwmon_channel_info * const lm92_info [] = {
267+ HWMON_CHANNEL_INFO (chip , HWMON_C_ALARMS ),
268+ HWMON_CHANNEL_INFO (temp ,
269+ HWMON_T_INPUT |
270+ HWMON_T_MIN | HWMON_T_MIN_HYST |
271+ HWMON_T_MAX | HWMON_T_MAX_HYST |
272+ HWMON_T_CRIT | HWMON_T_CRIT_HYST |
273+ HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
274+ HWMON_T_CRIT_ALARM ),
275+ NULL
276+ };
227277
228- return sprintf (buf , "%d\n" , (temp >> bitnr ) & 1 );
229- }
278+ static const struct hwmon_ops lm92_hwmon_ops = {
279+ .is_visible = lm92_is_visible ,
280+ .read = lm92_read ,
281+ .write = lm92_write ,
282+ };
230283
231- static SENSOR_DEVICE_ATTR_RO (temp1_input , temp , t_input ) ;
232- static SENSOR_DEVICE_ATTR_RW (temp1_crit , temp , t_crit ) ;
233- static SENSOR_DEVICE_ATTR_RW (temp1_crit_hyst , temp_hyst , t_crit ) ;
234- static SENSOR_DEVICE_ATTR_RW (temp1_min , temp , t_min ) ;
235- static DEVICE_ATTR_RO (temp1_min_hyst );
236- static SENSOR_DEVICE_ATTR_RW (temp1_max , temp , t_max ) ;
237- static SENSOR_DEVICE_ATTR_RO (temp1_max_hyst , temp_hyst , t_max ) ;
238- static DEVICE_ATTR_RO (alarms );
239- static SENSOR_DEVICE_ATTR_RO (temp1_crit_alarm , alarm , 2 ) ;
240- static SENSOR_DEVICE_ATTR_RO (temp1_min_alarm , alarm , 0 ) ;
241- static SENSOR_DEVICE_ATTR_RO (temp1_max_alarm , alarm , 1 ) ;
284+ static const struct hwmon_chip_info lm92_chip_info = {
285+ .ops = & lm92_hwmon_ops ,
286+ .info = lm92_info ,
287+ };
242288
243289/*
244290 * Detection and registration
@@ -249,22 +295,6 @@ static int lm92_init_client(struct regmap *regmap)
249295 return regmap_clear_bits (regmap , LM92_REG_CONFIG , 0x01 );
250296}
251297
252- static struct attribute * lm92_attrs [] = {
253- & sensor_dev_attr_temp1_input .dev_attr .attr ,
254- & sensor_dev_attr_temp1_crit .dev_attr .attr ,
255- & sensor_dev_attr_temp1_crit_hyst .dev_attr .attr ,
256- & sensor_dev_attr_temp1_min .dev_attr .attr ,
257- & dev_attr_temp1_min_hyst .attr ,
258- & sensor_dev_attr_temp1_max .dev_attr .attr ,
259- & sensor_dev_attr_temp1_max_hyst .dev_attr .attr ,
260- & dev_attr_alarms .attr ,
261- & sensor_dev_attr_temp1_crit_alarm .dev_attr .attr ,
262- & sensor_dev_attr_temp1_min_alarm .dev_attr .attr ,
263- & sensor_dev_attr_temp1_max_alarm .dev_attr .attr ,
264- NULL
265- };
266- ATTRIBUTE_GROUPS (lm92 );
267-
268298/* Return 0 if detection is successful, -ENODEV otherwise */
269299static int lm92_detect (struct i2c_client * new_client ,
270300 struct i2c_board_info * info )
@@ -373,9 +403,8 @@ static int lm92_probe(struct i2c_client *client)
373403 if (err )
374404 return err ;
375405
376- hwmon_dev = devm_hwmon_device_register_with_groups (dev ,
377- client -> name ,
378- data , lm92_groups );
406+ hwmon_dev = devm_hwmon_device_register_with_info (dev , client -> name , data ,
407+ & lm92_chip_info , NULL );
379408 return PTR_ERR_OR_ZERO (hwmon_dev );
380409}
381410
0 commit comments