* [lm-sensors] Supporting ADT7481 temperature sensor
@ 2009-01-12 12:18
2009-01-12 18:49 ` Hans de Goede
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: @ 2009-01-12 12:18 UTC (permalink / raw)
To: lm-sensors
Hello,
I am tasked with writing linux kernel support for the ADT7481 sensor.
This sensor is a dual remote, single local, sensor with an extended
temperature
range capability on the remote sensors.
Most of the register layout of the device is compliant with the LM90
driver but unfortunately the official manufacturer ID and device ID
registers are not in
a LM90 compliant location.
The LM90 driver supports the ADT7481 extended temperature range
registers through it's
ADT7461 support.
The ADT7481 does have register values at 0xfe and 0xff but they are not
documented in
the datasheet.
Here is an i2cdump output:
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 67 6b 00 24 08 9a 13 a9 13 24 08 9a 13 a9 13 00 gk.$?????$?????.
10: 40 00 00 00 00 00 00 00 00 a4 00 00 00 00 00 00 @........?......
20: 98 05 07 00 00 00 00 00 00 00 00 00 00 00 00 00 ???.............
30: 6d ae 13 c0 00 00 00 00 00 a9 00 00 00 81 41 02 m???.....?...?A?
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
70: 08 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 ?..?............
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 62 ..............Ab
The official manufacturer ID register is at 0x3e and the official device
ID register is at
0x3d.
My question is whether it would be better to?
1. Modify the lm90 driver, using undocumented registers for detection
and adding second
remote channel support
Or
2. Write a new driver from scratch but borrow code from the existing
LM90 driver
I would like to get this driver included into the kernel.
Thanks for any feedback.
Malcolm Crossley
Malcolm Crossley, Software Engineer,
Embedded Systems, GE Fanuc Intelligent Platforms
GE Fanuc Intelligent Platforms Ltd, registered in England and Wales
(3828642)
at 100 Barbirolli Square, Manchester, M2 3AB, VAT GB 729 849 476
_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor @ 2009-01-12 18:49 ` Hans de Goede 2009-01-14 10:29 ` Jean Delvare ` (13 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Hans de Goede @ 2009-01-12 18:49 UTC (permalink / raw) To: lm-sensors Crossley, Malcolm (GE EntSol, Intelligent Platforms) wrote: > Hello, > > I am tasked with writing linux kernel support for the ADT7481 sensor. > This sensor is a dual remote, single local, sensor with an extended > temperature > range capability on the remote sensors. > > Most of the register layout of the device is compliant with the LM90 > driver but unfortunately the official manufacturer ID and device ID > registers are not in > a LM90 compliant location. > > The LM90 driver supports the ADT7481 extended temperature range > registers through it's > ADT7461 support. > > The ADT7481 does have register values at 0xfe and 0xff but they are not > documented in > the datasheet. > > Here is an i2cdump output: > 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef > 00: 67 6b 00 24 08 9a 13 a9 13 24 08 9a 13 a9 13 00 gk.$?????$?????. > 10: 40 00 00 00 00 00 00 00 00 a4 00 00 00 00 00 00 @........?...... > 20: 98 05 07 00 00 00 00 00 00 00 00 00 00 00 00 00 ???............. > 30: 6d ae 13 c0 00 00 00 00 00 a9 00 00 00 81 41 02 m???.....?...?A? > 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 70: 08 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 ?..?............ > 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 62 ..............Ab > > The official manufacturer ID register is at 0x3e and the official device > ID register is at > 0x3d. > > My question is whether it would be better to? > 1. Modify the lm90 driver, using undocumented registers for detection > and adding second > remote channel support > Or > 2. Write a new driver from scratch but borrow code from the existing > LM90 driver > > I would like to get this driver included into the kernel. > I think one would be the best, if the changes are not to invasive (which they probably are not). Regards, Hans _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 18:49 ` Hans de Goede @ 2009-01-14 10:29 ` Jean Delvare 2009-01-14 11:50 ` ` (12 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Jean Delvare @ 2009-01-14 10:29 UTC (permalink / raw) To: lm-sensors On Mon, 12 Jan 2009 19:49:04 +0100, Hans de Goede wrote: > Crossley, Malcolm (GE EntSol, Intelligent Platforms) wrote: > > Hello, > > > > I am tasked with writing linux kernel support for the ADT7481 sensor. > > This sensor is a dual remote, single local, sensor with an extended > > temperature > > range capability on the remote sensors. > > > > Most of the register layout of the device is compliant with the LM90 > > driver but unfortunately the official manufacturer ID and device ID > > registers are not in > > a LM90 compliant location. > > > > The LM90 driver supports the ADT7481 extended temperature range > > registers through it's > > ADT7461 support. > > > > The ADT7481 does have register values at 0xfe and 0xff but they are not > > documented in > > the datasheet. > > > > Here is an i2cdump output: > > 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef > > 00: 67 6b 00 24 08 9a 13 a9 13 24 08 9a 13 a9 13 00 gk.$?????$?????. > > 10: 40 00 00 00 00 00 00 00 00 a4 00 00 00 00 00 00 @........?...... > > 20: 98 05 07 00 00 00 00 00 00 00 00 00 00 00 00 00 ???............. > > 30: 6d ae 13 c0 00 00 00 00 00 a9 00 00 00 81 41 02 m???.....?...?A? > > 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > 70: 08 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 ?..?............ > > 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 62 ..............Ab > > > > The official manufacturer ID register is at 0x3e and the official device > > ID register is at > > 0x3d. > > > > My question is whether it would be better to? > > 1. Modify the lm90 driver, using undocumented registers for detection > > and adding second > > remote channel support > > Or > > 2. Write a new driver from scratch but borrow code from the existing > > LM90 driver > > > > I would like to get this driver included into the kernel. > > > > I think one would be the best, if the changes are not to invasive (which they > probably are not). I beg to disagree. The lm90 driver already supports a lot of different devices. The ADT7481 differs in a significant way in that it supports an additional external sensor. This is probably the right time to start a new driver. Then maybe the support for the ADT7461 can be moved to this new driver so that the lm90 driver can be simplified a bit. For now it would be good to add the ADT7481 to wiki/Devices and detection to sensors-detect. Malcolm, if you want an account on lm-sensors' wiki, please send _me_ the output of the following command: htdigest -c $user-passwd lm-sensors/i2c $user where $user is your desired login. Can you please also send us a patch against the latest version of sensors-detect: http://www.lm-sensors.org/svn/lm-sensors/branches/lm-sensors-3.0.0/prog/detect/sensors-detect adding detection of the ADT7481? Thanks, -- Jean Delvare _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 18:49 ` Hans de Goede 2009-01-14 10:29 ` Jean Delvare @ 2009-01-14 11:50 ` 2009-01-14 14:55 ` Jean Delvare ` (11 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: @ 2009-01-14 11:50 UTC (permalink / raw) To: lm-sensors Jean Delvare wrote: > On Mon, 12 Jan 2009 19:49:04 +0100, Hans de Goede wrote: >> Crossley, Malcolm (GE EntSol, Intelligent Platforms) wrote: >>> Hello, >>> >>> I am tasked with writing linux kernel support for the ADT7481 >>> sensor. This sensor is a dual remote, single local, sensor with an >>> extended temperature range capability on the remote sensors. >>> >>> Most of the register layout of the device is compliant with the LM90 >>> driver but unfortunately the official manufacturer ID and device ID >>> registers are not in a LM90 compliant location. >>> >>> The LM90 driver supports the ADT7481 extended temperature range >>> registers through it's ADT7461 support. >>> >>> The ADT7481 does have register values at 0xfe and 0xff but they are >>> not documented in the datasheet. >>> >>> Here is an i2cdump output: >>> 0 1 2 3 4 5 6 7 8 9 a b c d e f >>> 0123456789abcdef 00: 67 6b 00 24 08 9a 13 a9 13 24 08 9a 13 a9 13 >>> 00 gk.$?????$?????. 10: 40 00 00 00 00 00 00 00 00 a4 00 00 00 >>> 00 00 00 @........?...... 20: 98 05 07 00 00 00 00 00 00 00 00 >>> 00 00 00 00 00 ???............. 30: 6d ae 13 c0 00 00 00 00 00 >>> a9 00 00 00 81 41 02 m???.....?...?A? 40: 00 00 00 00 00 00 00 >>> 00 00 00 00 00 00 00 00 00 ................ 50: 00 00 00 00 00 >>> 00 00 00 00 00 00 00 00 00 00 00 ................ 60: 00 00 00 >>> 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 70: 08 >>> 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 ?..?............ >>> 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> ................ 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> 00 ................ a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> 00 00 00 ................ b0: 00 00 00 00 00 00 00 00 00 00 00 >>> 00 00 00 00 00 ................ c0: 00 00 00 00 00 00 00 00 00 >>> 00 00 00 00 00 00 00 ................ d0: 00 00 00 00 00 00 00 >>> 00 00 00 00 00 00 00 00 00 ................ e0: 00 00 00 00 00 >>> 00 00 00 00 00 00 00 00 00 00 00 ................ f0: 00 00 00 >>> 00 00 00 00 00 00 00 00 00 00 00 41 62 ..............Ab >>> >>> The official manufacturer ID register is at 0x3e and the official >>> device ID register is at 0x3d. >>> >>> My question is whether it would be better to? >>> 1. Modify the lm90 driver, using undocumented registers for >>> detection and adding second >>> remote channel support >>> Or >>> 2. Write a new driver from scratch but borrow code from the >>> existing LM90 driver >>> >>> I would like to get this driver included into the kernel. >>> >> >> I think one would be the best, if the changes are not to invasive >> (which they probably are not). > > I beg to disagree. The lm90 driver already supports a lot of > different devices. The ADT7481 differs in a significant way in that > it supports an additional external sensor. This is probably the right > time to start a new driver. Then maybe the support for the ADT7461 > can be moved to this new driver so that the lm90 driver can be > simplified a bit. I attempted to modify the lm90 driver and discovered that fairly invasive changes were required to support a larger driver structure for storing the sensors values. I would not move the ADT7461 into a driver for the ADT7481 because the structure would differ as above ( structure for 2 channel device vs 3 channel device) and the registers for device detection are in different locations. I have created a separate ADT7481 driver based upon the LM90 structure. It's still needs a clean up but it's been tested and it has PEC support included (full PEC support not the half adm1032 support). > > For now it would be good to add the ADT7481 to wiki/Devices and > detection to sensors-detect. > Will do the wiki entry, see below for sensors-detect. > Malcolm, if you want an account on lm-sensors' wiki, please send _me_ > the output of the following command: htdigest -c $user-passwd > lm-sensors/i2c $user where $user is your desired login. > Sent in another email. > Can you please also send us a patch against the latest version of > sensors-detect: > http://www.lm-sensors.org/svn/lm-sensors/branches/lm-sensors-3.0.0/prog/ detect/sensors-detect > adding detection of the ADT7481? > > Thanks, Unfortunately I can only use Outlook at work currently and so it will be difficult to send patches to mailing lists without breaking them. I have a colleague(Martyn Welch) with a better email setup who can send patches on my behalf. I am working towards a better email setup but it will take some weeks (IT issues). -- Malcolm Crossley, Software Engineer, Embedded Systems, GE Fanuc Intelligent Platforms GE Fanuc Intelligent Platforms Ltd, registered in England and Wales (3828642) at 100 Barbirolli Square, Manchester, M2 3AB, VAT GB 729 849 476 _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (2 preceding siblings ...) 2009-01-14 11:50 ` @ 2009-01-14 14:55 ` Jean Delvare 2012-10-12 10:30 ` Jia Hongtao-B38951 ` (10 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Jean Delvare @ 2009-01-14 14:55 UTC (permalink / raw) To: lm-sensors Hi Malcolm, On Wed, 14 Jan 2009 11:50:33 -0000, Crossley, Malcolm (GE EntSol, Intelligent Platforms) wrote: > Jean Delvare wrote: > > I beg to disagree. The lm90 driver already supports a lot of > > different devices. The ADT7481 differs in a significant way in that > > it supports an additional external sensor. This is probably the right > > time to start a new driver. Then maybe the support for the ADT7461 > > can be moved to this new driver so that the lm90 driver can be > > simplified a bit. > > I attempted to modify the lm90 driver and discovered that fairly > invasive changes were required to support a larger driver structure for > storing the sensors values. > > I would not move the ADT7461 into a driver for the ADT7481 because the > structure would differ as above ( structure for 2 channel device vs 3 > channel device) and the registers for device detection are in different > locations. The larger structure isn't such a big problem. It is perfectly OK to use the larger structure for all devices, we do that all the time. The difference isn't that much anyway, we are speaking of a few dozen bytes here. The different identification registers aren't necessarily a blocking factor either. My main motivation for proposing to move ADT7461 support is that there are a lot of data->kind = adt7461 conditionals in the lm90 driver at the moment, which would go away with the ADT7461 support. But anyway this can be revisited later, if it happens it doesn't have to happen at the same time as adding support for the ADT7481, which is your primary goal. > I have created a separate ADT7481 driver based upon the LM90 structure. > It's still needs a clean up but it's been tested and it has PEC support > included (full PEC support not the half adm1032 support). Ah, if the PEC support is better it's good news. The ADM1032 implementation was really a pain :( If I had not needed it to test the i2c-core part, I would probably never have implemented it. > > Can you please also send us a patch against the latest version of > > sensors-detect, adding detection of the ADT7481? > > Unfortunately I can only use Outlook at work currently and so it will > be difficult to send patches to mailing lists without breaking them. I > have a colleague(Martyn Welch) with a better email setup who can send > patches on my behalf. I am working towards a better email setup but it > will take some weeks (IT issues). Outlook isn't so bad that it would screw patches even sent as attachments, would it? Oh well, maybe... But of course if Martyn sends the patches that's fine with us. -- Jean Delvare _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (3 preceding siblings ...) 2009-01-14 14:55 ` Jean Delvare @ 2012-10-12 10:30 ` Jia Hongtao-B38951 2012-10-12 13:18 ` Tabi Timur-B04825 ` (9 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Jia Hongtao-B38951 @ 2012-10-12 10:30 UTC (permalink / raw) To: lm-sensors [-- Attachment #2: Type: text/plain, Size: 367 bytes --] Hello all, I'm looking for ADT7481 support in kernel. I got some messages here: http://www.spinics.net/lists/lm-sensors/msg25066.html It seems this patch has not been upstreamed yet. Does anyone know where to find the patch? If not could anyone know a quick way to support ADT7481 in kernel? Thanks. --- Best Regards, Hongtao [-- Attachment #3: Type: text/html, Size: 5096 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (4 preceding siblings ...) 2012-10-12 10:30 ` Jia Hongtao-B38951 @ 2012-10-12 13:18 ` Tabi Timur-B04825 2012-10-12 15:58 ` Jean Delvare ` (8 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Tabi Timur-B04825 @ 2012-10-12 13:18 UTC (permalink / raw) To: lm-sensors On Fri, Oct 12, 2012 at 5:30 AM, Jia Hongtao-B38951 <B38951@freescale.com> wrote: > I’m looking for ADT7481 support in kernel. > > I got some messages here: > > http://www.spinics.net/lists/lm-sensors/msg25066.html > > It seems this patch has not been upstreamed yet. > > Does anyone know where to find the patch? Have you tried emailing Malcolm Crossley? -- Timur Tabi Linux kernel developer at Freescale _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (5 preceding siblings ...) 2012-10-12 13:18 ` Tabi Timur-B04825 @ 2012-10-12 15:58 ` Jean Delvare 2012-10-15 2:21 ` Jia Hongtao-B38951 ` (7 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Jean Delvare @ 2012-10-12 15:58 UTC (permalink / raw) To: lm-sensors On Fri, 12 Oct 2012 10:30:32 +0000, Jia Hongtao-B38951 wrote: > Hello all, > > > > I'm looking for ADT7481 support in kernel. > > I got some messages here: > > http://www.spinics.net/lists/lm-sensors/msg25066.html > > > > It seems this patch has not been upstreamed yet. > > > > Does anyone know where to find the patch? There was a discussion but no code was ever submitted. You should try contacting Malcolm, but it was long ago, he may have changed jobs or lost interest meanwhile. > If not could anyone know a quick way to support ADT7481 in kernel? You can try forcing ADT7461 support on your chip as apparently the ADT7481 implements a superset of the ADT7461 features. Find which i2c bus your chip is on, then from user space, do: # echo adt7461 $ADDR > /sys/bus/i2c/devices/i2c-$BUSNR/new_device where $ADDR is the hexadecimal 7-bit address address of your ADT7461 device, and $BUSNR the i2c bus number. Obviously you won't have support for the 2nd external sensor that way, but that's a start. -- Jean Delvare _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (6 preceding siblings ...) 2012-10-12 15:58 ` Jean Delvare @ 2012-10-15 2:21 ` Jia Hongtao-B38951 2012-10-15 2:22 ` Jia Hongtao-B38951 ` (6 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Jia Hongtao-B38951 @ 2012-10-15 2:21 UTC (permalink / raw) To: lm-sensors > -----Original Message----- > From: Tabi Timur-B04825 > Sent: Friday, October 12, 2012 9:19 PM > To: Jia Hongtao-B38951 > Cc: lm-sensors@lm-sensors.org > Subject: Re: [lm-sensors] Supporting ADT7481 temperature sensor > > On Fri, Oct 12, 2012 at 5:30 AM, Jia Hongtao-B38951 <B38951@freescale.com> > wrote: > > > I'm looking for ADT7481 support in kernel. > > > > I got some messages here: > > > > http://www.spinics.net/lists/lm-sensors/msg25066.html > > > > It seems this patch has not been upstreamed yet. > > > > Does anyone know where to find the patch? > > Have you tried emailing Malcolm Crossley? Yes, but the email address is not valid anymore :( > > -- > Timur Tabi > Linux kernel developer at Freescale _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (7 preceding siblings ...) 2012-10-15 2:21 ` Jia Hongtao-B38951 @ 2012-10-15 2:22 ` Jia Hongtao-B38951 2013-08-30 12:04 ` Mercier Ivan ` (5 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Jia Hongtao-B38951 @ 2012-10-15 2:22 UTC (permalink / raw) To: lm-sensors > -----Original Message----- > From: Jean Delvare [mailto:khali@linux-fr.org] > Sent: Friday, October 12, 2012 11:58 PM > To: Jia Hongtao-B38951 > Cc: lm-sensors@lm-sensors.org > Subject: Re: [lm-sensors] Supporting ADT7481 temperature sensor > > On Fri, 12 Oct 2012 10:30:32 +0000, Jia Hongtao-B38951 wrote: > > Hello all, > > > > > > > > I'm looking for ADT7481 support in kernel. > > > > I got some messages here: > > > > http://www.spinics.net/lists/lm-sensors/msg25066.html > > > > > > > > It seems this patch has not been upstreamed yet. > > > > > > > > Does anyone know where to find the patch? > > There was a discussion but no code was ever submitted. You should try > contacting Malcolm, but it was long ago, he may have changed jobs or lost > interest meanwhile. > > > If not could anyone know a quick way to support ADT7481 in kernel? > > You can try forcing ADT7461 support on your chip as apparently the > ADT7481 implements a superset of the ADT7461 features. Find which i2c bus > your chip is on, then from user space, do: > > # echo adt7461 $ADDR > /sys/bus/i2c/devices/i2c-$BUSNR/new_device > > where $ADDR is the hexadecimal 7-bit address address of your ADT7461 > device, and $BUSNR the i2c bus number. > > Obviously you won't have support for the 2nd external sensor that way, > but that's a start. > Got it. Thanks for your suggestions. - Hongtao. _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (8 preceding siblings ...) 2012-10-15 2:22 ` Jia Hongtao-B38951 @ 2013-08-30 12:04 ` Mercier Ivan 2013-08-30 16:21 ` Guenter Roeck ` (4 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Mercier Ivan @ 2013-08-30 12:04 UTC (permalink / raw) To: lm-sensors Hi everybody, I have a ADT7481 sensor and I would like to make it work. What the current status of this driver? Does somebody start writting some code? How can I start? Thanks, Ivan _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (9 preceding siblings ...) 2013-08-30 12:04 ` Mercier Ivan @ 2013-08-30 16:21 ` Guenter Roeck 2013-08-31 12:56 ` Jean Delvare ` (3 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Guenter Roeck @ 2013-08-30 16:21 UTC (permalink / raw) To: lm-sensors On Fri, Aug 30, 2013 at 02:04:53PM +0200, Mercier Ivan wrote: > Hi everybody, > I have a ADT7481 sensor and I would like to make it work. > What the current status of this driver? > Does somebody start writting some code? > How can I start? > If you compare the datasheet with other temperature sensor datasheets, you'll notice similarities with ADT7461 and MAX6696, both of which are supported by the lm90 driver. You can start from there, look for similarities and differences, add support for ADC7481 to the lm90 driver, and submit a patch to get it integrated. Guenter _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (10 preceding siblings ...) 2013-08-30 16:21 ` Guenter Roeck @ 2013-08-31 12:56 ` Jean Delvare 2013-08-31 13:51 ` Guenter Roeck ` (2 subsequent siblings) 14 siblings, 0 replies; 16+ messages in thread From: Jean Delvare @ 2013-08-31 12:56 UTC (permalink / raw) To: lm-sensors On Fri, 30 Aug 2013 09:21:27 -0700, Guenter Roeck wrote: > On Fri, Aug 30, 2013 at 02:04:53PM +0200, Mercier Ivan wrote: > > Hi everybody, > > I have a ADT7481 sensor and I would like to make it work. > > What the current status of this driver? > > Does somebody start writting some code? > > How can I start? > > > If you compare the datasheet with other temperature sensor datasheets, you'll > notice similarities with ADT7461 and MAX6696, both of which are supported by the > lm90 driver. You can start from there, look for similarities and differences, > add support for ADT7481 to the lm90 driver, and submit a patch to get it > integrated. For reference, lm90 vs. new driver was already discussed here: http://lists.lm-sensors.org/pipermail/lm-sensors/2009-January/025132.html Back then, Malcolm Crossley (Cc'd) was working on adding support for the ADT7481. It was four years ago, I have no idea if it actually happened or not. Malcolm, do you have code you would like to share with Ivan? -- Jean Delvare _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (11 preceding siblings ...) 2013-08-31 12:56 ` Jean Delvare @ 2013-08-31 13:51 ` Guenter Roeck 2013-09-03 11:00 ` Mercier Ivan 2013-09-10 7:26 ` Jean Delvare 14 siblings, 0 replies; 16+ messages in thread From: Guenter Roeck @ 2013-08-31 13:51 UTC (permalink / raw) To: lm-sensors On 08/31/2013 05:56 AM, Jean Delvare wrote: > On Fri, 30 Aug 2013 09:21:27 -0700, Guenter Roeck wrote: >> On Fri, Aug 30, 2013 at 02:04:53PM +0200, Mercier Ivan wrote: >>> Hi everybody, >>> I have a ADT7481 sensor and I would like to make it work. >>> What the current status of this driver? >>> Does somebody start writting some code? >>> How can I start? >>> >> If you compare the datasheet with other temperature sensor datasheets, you'll >> notice similarities with ADT7461 and MAX6696, both of which are supported by the >> lm90 driver. You can start from there, look for similarities and differences, >> add support for ADT7481 to the lm90 driver, and submit a patch to get it >> integrated. > > For reference, lm90 vs. new driver was already discussed here: > http://lists.lm-sensors.org/pipermail/lm-sensors/2009-January/025132.html > the lm90 driver changed significantly since then, though. Support for the third sensor is there now, and adding a new sensor type is much easier. I only had a quick glance, but ADT7481 looks pretty similar to MAX6696. Guenter > Back then, Malcolm Crossley (Cc'd) was working on adding support for > the ADT7481. It was four years ago, I have no idea if it actually > happened or not. Malcolm, do you have code you would like to share with > Ivan? > _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (12 preceding siblings ...) 2013-08-31 13:51 ` Guenter Roeck @ 2013-09-03 11:00 ` Mercier Ivan 2013-09-10 7:26 ` Jean Delvare 14 siblings, 0 replies; 16+ messages in thread From: Mercier Ivan @ 2013-09-03 11:00 UTC (permalink / raw) To: lm-sensors Thanks for your answers guys. At this moment, we have hardware troubles on remote sensor routing,there is too much noise. If we fix that and depending of which functions are needed and the time I have, I will code the driver. 2013/8/31 Guenter Roeck <linux@roeck-us.net>: > On 08/31/2013 05:56 AM, Jean Delvare wrote: >> >> On Fri, 30 Aug 2013 09:21:27 -0700, Guenter Roeck wrote: >>> >>> On Fri, Aug 30, 2013 at 02:04:53PM +0200, Mercier Ivan wrote: >>>> >>>> Hi everybody, >>>> I have a ADT7481 sensor and I would like to make it work. >>>> What the current status of this driver? >>>> Does somebody start writting some code? >>>> How can I start? >>>> >>> If you compare the datasheet with other temperature sensor datasheets, >>> you'll >>> notice similarities with ADT7461 and MAX6696, both of which are supported >>> by the >>> lm90 driver. You can start from there, look for similarities and >>> differences, >>> add support for ADT7481 to the lm90 driver, and submit a patch to get it >>> integrated. >> >> >> For reference, lm90 vs. new driver was already discussed here: >> http://lists.lm-sensors.org/pipermail/lm-sensors/2009-January/025132.html >> > > the lm90 driver changed significantly since then, though. Support for > the third sensor is there now, and adding a new sensor type is much easier. > I only had a quick glance, but ADT7481 looks pretty similar to MAX6696. > > Guenter > > >> Back then, Malcolm Crossley (Cc'd) was working on adding support for >> the ADT7481. It was four years ago, I have no idea if it actually >> happened or not. Malcolm, do you have code you would like to share with >> Ivan? >> > _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor ` (13 preceding siblings ...) 2013-09-03 11:00 ` Mercier Ivan @ 2013-09-10 7:26 ` Jean Delvare 14 siblings, 0 replies; 16+ messages in thread From: Jean Delvare @ 2013-09-10 7:26 UTC (permalink / raw) To: lm-sensors [-- Attachment #1: Type: text/plain, Size: 1001 bytes --] Hi Guenter, Ivan, On Sat, 31 Aug 2013 06:51:14 -0700, Guenter Roeck wrote: > > For reference, lm90 vs. new driver was already discussed here: > > http://lists.lm-sensors.org/pipermail/lm-sensors/2009-January/025132.html > > the lm90 driver changed significantly since then, though. Support for > the third sensor is there now, and adding a new sensor type is much easier. > I only had a quick glance, but ADT7481 looks pretty similar to MAX6696. > > Guenter > > > Back then, Malcolm Crossley (Cc'd) was working on adding support for > > the ADT7481. It was four years ago, I have no idea if it actually > > happened or not. I got my hands on the code originally written by Malcolm. The code has been used so it must be working, but it was never submitted for upstream inclusion. I am attaching it for reference. That being said, as Guenter mentioned, the lm90 driver evolved a lot since then, so while a separate driver made more sense back then, it may no longer be the case. -- Jean Delvare [-- Attachment #2: add-adt7481-driver.patch --] [-- Type: text/x-patch, Size: 23984 bytes --] Add support for the ADT7481 temperature sensor chip including extended From: Malcolm Crossley <malcolm.crossley@ge.com> temperature range support on the remote sensors. --- drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 drivers/hwmon/adt7481.c | 730 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 741 insertions(+), 0 deletions(-) create mode 100644 drivers/hwmon/adt7481.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 9be8e17..5d7898a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -190,6 +190,16 @@ config SENSORS_ADT7462 This driver can also be built as a module. If so, the module will be called adt7462. +config SENSORS_ADT7481 + tristate "Analog Devices ADT7481" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Analog Devices + ADT7481 temperature monitoring chips. + + This driver can also be built as a module. If so, the module + will be called adt7481. + config SENSORS_ADT7470 tristate "Analog Devices ADT7470" depends on I2C && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 4aa1a3d..b68379f 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o +obj-$(CONFIG_SENSORS_ADT7481) += adt7481.o obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_AMS) += ams/ obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o diff --git a/drivers/hwmon/adt7481.c b/drivers/hwmon/adt7481.c new file mode 100644 index 0000000..86a644e --- /dev/null +++ b/drivers/hwmon/adt7481.c @@ -0,0 +1,730 @@ +/* + * adt7481.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (C) 2010 GE Intelligent Platforms + * Author: Malcolm Crossley <malcolm.crossley@ge.com> + * Based upon ADT7462 and LM90 driver + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/i2c.h> +#include <linux/hwmon-sysfs.h> +#include <linux/hwmon.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/sysfs.h> + +/* + * Addresses to scan + * The ADT7481 is at address 0x4c and the ADT7481-1 is at address + * 0x4d. + */ + +static const unsigned short normal_i2c[] = { + 0x4c, 0x4d, I2C_CLIENT_END }; + +/* + * The ADT7481 registers + */ + +#define ADT7481_REG_R_MAN_ID 0x3E +#define ADT7481_REG_R_CHIP_ID 0x3D +#define ADT7481_REG_R_CONFIG1 0x03 +#define ADT7481_REG_W_CONFIG1 0x09 +#define ADT7481_REG_R_CONFIG2 0x24 +#define ADT7481_REG_W_CONFIG2 0x24 +#define ADT7481_REG_R_CONVRATE 0x04 +#define ADT7481_REG_W_CONVRATE 0x0A +#define ADT7481_REG_R_STATUS 0x02 +#define ADT7481_REG_R_LOCAL_TEMP 0x00 +#define ADT7481_REG_R_LOCAL_HIGH 0x05 +#define ADT7481_REG_W_LOCAL_HIGH 0x0B +#define ADT7481_REG_R_LOCAL_LOW 0x06 +#define ADT7481_REG_W_LOCAL_LOW 0x0C +#define ADT7481_REG_R_LOCAL_CRIT 0x20 +#define ADT7481_REG_W_LOCAL_CRIT 0x20 +#define ADT7481_REG_R_REMOTE1_TEMPH 0x01 +#define ADT7481_REG_R_REMOTE1_TEMPL 0x10 +#define ADT7481_REG_R_REMOTE1_OFFSH 0x11 +#define ADT7481_REG_W_REMOTE1_OFFSH 0x11 +#define ADT7481_REG_R_REMOTE1_OFFSL 0x12 +#define ADT7481_REG_W_REMOTE1_OFFSL 0x12 +#define ADT7481_REG_R_REMOTE1_HIGHH 0x07 +#define ADT7481_REG_W_REMOTE1_HIGHH 0x0D +#define ADT7481_REG_R_REMOTE1_HIGHL 0x13 +#define ADT7481_REG_W_REMOTE1_HIGHL 0x13 +#define ADT7481_REG_R_REMOTE1_LOWH 0x08 +#define ADT7481_REG_W_REMOTE1_LOWH 0x0E +#define ADT7481_REG_R_REMOTE1_LOWL 0x14 +#define ADT7481_REG_W_REMOTE1_LOWL 0x14 +#define ADT7481_REG_R_REMOTE1_CRIT 0x19 +#define ADT7481_REG_W_REMOTE1_CRIT 0x19 +#define ADT7481_REG_R_REMOTE2_TEMPH 0x30 +#define ADT7481_REG_R_REMOTE2_TEMPL 0x33 +#define ADT7481_REG_R_REMOTE2_OFFSH 0x34 +#define ADT7481_REG_W_REMOTE2_OFFSH 0x34 +#define ADT7481_REG_R_REMOTE2_OFFSL 0x35 +#define ADT7481_REG_W_REMOTE2_OFFSL 0x35 +#define ADT7481_REG_R_REMOTE2_HIGHH 0x31 +#define ADT7481_REG_W_REMOTE2_HIGHH 0x31 +#define ADT7481_REG_R_REMOTE2_HIGHL 0x36 +#define ADT7481_REG_W_REMOTE2_HIGHL 0x36 +#define ADT7481_REG_R_REMOTE2_LOWH 0x32 +#define ADT7481_REG_W_REMOTE2_LOWH 0x32 +#define ADT7481_REG_R_REMOTE2_LOWL 0x37 +#define ADT7481_REG_W_REMOTE2_LOWL 0x37 +#define ADT7481_REG_R_REMOTE2_CRIT 0x39 +#define ADT7481_REG_W_REMOTE2_CRIT 0x39 + +#define ADT7481_REG_R_TCRIT_HYST 0x21 +#define ADT7481_REG_W_TCRIT_HYST 0x21 + +/* + * Device flags + */ +#define ADT7481_FLAG_ADT7461_EXT 0x01 /* ADT7461 extended mode */ + +/* + * Functions declaration + */ + +static int adt7481_detect(struct i2c_client *client, + struct i2c_board_info *info); +static int adt7481_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static void adt7481_init_client(struct i2c_client *client); +static int adt7481_remove(struct i2c_client *client); +static struct adt7481_data *adt7481_update_device(struct device *dev); + +/* + * Driver data (common to all clients) + */ + +static const struct i2c_device_id adt7481_id[] = { + { "adt7481", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adt7481_id); + +static struct i2c_driver adt7481_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "adt7481", + }, + .probe = adt7481_probe, + .remove = adt7481_remove, + .id_table = adt7481_id, + .detect = adt7481_detect, + .address_list = normal_i2c, +}; + +/* + * Client data (each client gets its own) + */ + +struct adt7481_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + int flags; + + /* registers values */ + s8 temp8[5]; /* 0: local low limit + 1: local high limit + 2: local critical limit + 3: remote1 critical limit + 4: remote2 critical limit */ + s16 temp11[9]; /* 0: remote1 input + 1: remote1 low limit + 2: remote1 high limit + 3: remote1 offset + 4: remote2 input + 5: remote2 low limit + 6: remote2 high limit + 7: remote2 offset + 8: local input */ + u8 temp_hyst; + u8 alarms; /* bitvector */ +}; + +/* + * Conversions + * For local temperatures and limits, critical limits and the hysteresis + * value, the ADT7481 uses signed 8-bit values with LSB = 1 degree Celsius. + * For remote temperatures and limits, it uses signed 11-bit values with + * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. Some + * Maxim chips use unsigned values. + */ + + +static inline int temp_from_u8(u8 val) +{ + return val * 1000; +} + +static inline int temp_from_u16(u16 val) +{ + return val / 32 * 125; +} + +static u8 hyst_to_reg(long val) +{ + if (val <= 0) + return 0; + if (val >= 30500) + return 31; + return (val + 500) / 1000; +} + +/* + * ADT7461 in compatibility mode is almost identical to ADT7481 except that + * attempts to write values that are outside the range 0 < temp < 127 are + * treated as the boundary value. + * + * ADT7461 in "extended mode" operation uses unsigned integers offset by + * 64 (e.g., 0 -> -64 degC). The range is restricted to -64..191 degC. + */ +static inline int temp_from_u8_adt7461(struct adt7481_data *data, u8 val) +{ + if (data->flags & ADT7481_FLAG_ADT7461_EXT) + return (val - 64) * 1000; + else + return temp_from_u8(val); +} + +static inline int temp_from_u16_adt7461(struct adt7481_data *data, u16 val) +{ + if (data->flags & ADT7481_FLAG_ADT7461_EXT) + return (val - 0x4000) / 64 * 250; + else + return temp_from_u16(val); +} + +static u8 temp_to_u8_adt7461(struct adt7481_data *data, long val) +{ + if (data->flags & ADT7481_FLAG_ADT7461_EXT) { + if (val <= -64000) + return 0; + if (val >= 191000) + return 0xFF; + return (val + 500 + 64000) / 1000; + } else { + if (val <= 0) + return 0; + if (val >= 127000) + return 127; + return (val + 500) / 1000; + } +} + +static u16 temp_to_u16_adt7461(struct adt7481_data *data, long val) +{ + if (data->flags & ADT7481_FLAG_ADT7461_EXT) { + if (val <= -64000) + return 0; + if (val >= 191750) + return 0xFFC0; + return (val + 64000 + 125) / 250 * 64; + } else { + if (val <= 0) + return 0; + if (val >= 127750) + return 0x7FC0; + return (val + 125) / 250 * 64; + } +} + +/* + * Sysfs stuff + */ + +static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7481_data *data = adt7481_update_device(dev); + int temp; + + temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + static const u8 reg[5] = { + ADT7481_REG_W_LOCAL_LOW, + ADT7481_REG_W_LOCAL_HIGH, + ADT7481_REG_W_LOCAL_CRIT, + ADT7481_REG_W_REMOTE1_CRIT, + ADT7481_REG_W_REMOTE2_CRIT + }; + + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7481_data *data = i2c_get_clientdata(client); + long val; + int nr = attr->index; + strict_strtol(buf, 10, &val); + + mutex_lock(&data->update_lock); + data->temp8[nr] = temp_to_u8_adt7461(data, val); + i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7481_data *data = adt7481_update_device(dev); + int temp; + + temp = temp_from_u16_adt7461(data, data->temp11[attr->index]); + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + static const u8 reg[6] = { + ADT7481_REG_W_REMOTE1_LOWH, + ADT7481_REG_W_REMOTE1_LOWL, + ADT7481_REG_W_REMOTE1_HIGHH, + ADT7481_REG_W_REMOTE1_HIGHL, + ADT7481_REG_W_REMOTE1_OFFSH, + ADT7481_REG_W_REMOTE1_OFFSL, + }; + + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7481_data *data = i2c_get_clientdata(client); + long val; + int nr = attr->index; + strict_strtol(buf, 10, &val); + + + mutex_lock(&data->update_lock); + data->temp11[nr] = temp_to_u16_adt7461(data, val); + i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], + data->temp11[nr] >> 8); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t show_temphyst(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7481_data *data = adt7481_update_device(dev); + int temp; + + temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); + return sprintf(buf, "%d\n", temp - temp_from_u8(data->temp_hyst)); +} + +static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7481_data *data = i2c_get_clientdata(client); + long val; + int temp; + strict_strtol(buf, 10, &val); + + mutex_lock(&data->update_lock); + temp = temp_from_u8_adt7461(data, data->temp8[2]); + data->temp_hyst = hyst_to_reg(temp - val); + i2c_smbus_write_byte_data(client, ADT7481_REG_W_TCRIT_HYST, + data->temp_hyst); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, + char *buf) +{ + struct adt7481_data *data = adt7481_update_device(dev); + return sprintf(buf, "%d\n", data->alarms); +} + +static ssize_t show_alarm(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7481_data *data = adt7481_update_device(dev); + int bitnr = attr->index; + + return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp11, NULL, 8); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp11, NULL, 4); +static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, + set_temp8, 0); +static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 1); +static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 1); +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, + set_temp8, 1); +static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 2); +static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 6); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, + set_temp8, 2); +static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, + set_temp8, 3); +static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp8, + set_temp8, 4); +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, + set_temphyst, 2); +static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 3); +static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); +static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 3); +static SENSOR_DEVICE_ATTR(temp3_offset, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 3); + +/* Individual alarm files */ +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); +/* Raw alarm file for compatibility */ +static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + +static struct attribute *adt7481_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_offset.dev_attr.attr, + &sensor_dev_attr_temp3_offset.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group adt7481_group = { + .attrs = adt7481_attributes, +}; + +/* pec used for ADM1032 only */ +static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); +} + +static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + long val; + strict_strtol(buf, 10, &val); + + switch (val) { + case 0: + client->flags &= ~I2C_CLIENT_PEC; + break; + case 1: + client->flags |= I2C_CLIENT_PEC; + break; + default: + return -EINVAL; + } + + return count; +} + +static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); + +/* It is assumed that client->update_lock is held (unless we are in + detection or initialization steps). This matters when PEC is enabled, + because we don't want the address pointer to change between the write + byte and the read byte transactions. */ +static int adt7481_read_reg(struct i2c_client *client, u8 reg, u8 *value) +{ + int err; + + err = i2c_smbus_read_byte_data(client, reg); + + if (err < 0) { + dev_warn(&client->dev, "Register %#02x read failed (%d)\n", + reg, err); + return err; + } + *value = err; + + return 0; +} + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adt7481_detect(struct i2c_client *new_client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int man_id, chip_id; + const char *name = ""; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + man_id = i2c_smbus_read_byte_data(new_client, ADT7481_REG_R_MAN_ID); + if (man_id < 0) + return -ENODEV; + + chip_id = i2c_smbus_read_byte_data(new_client, ADT7481_REG_R_CHIP_ID); + if (chip_id < 0) + return -ENODEV; + + if ((man_id == 0x41) && (chip_id == 0x81)) { /* ADT7481 */ + if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) + info->flags |= I2C_CLIENT_PEC; + } else { + return -ENODEV; + } + + /* Fill the i2c board info */ + name = "adt7481"; + strlcpy(info->type, name, I2C_NAME_SIZE); + + return 0; +} + +static int adt7481_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = to_i2c_adapter(new_client->dev.parent); + struct adt7481_data *data; + int err; + + data = kzalloc(sizeof(struct adt7481_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + i2c_set_clientdata(new_client, data); + mutex_init(&data->update_lock); + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) + new_client->flags &= ~I2C_CLIENT_PEC; + + /* Initialize the ADT7481 chip */ + adt7481_init_client(new_client); + + /* Register sysfs hooks */ + err = sysfs_create_group(&new_client->dev.kobj, &adt7481_group); + if (err) + goto exit_free; + if (new_client->flags & I2C_CLIENT_PEC) { + err = device_create_file(&new_client->dev, &dev_attr_pec); + if (err) + goto exit_remove_files; + } + + data->hwmon_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove_files; + } + + return 0; + +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &adt7481_group); + device_remove_file(&new_client->dev, &dev_attr_pec); +exit_free: + kfree(data); +exit: + return err; +} + +static void adt7481_init_client(struct i2c_client *client) +{ + u8 config, config_orig; + struct adt7481_data *data = i2c_get_clientdata(client); + + /* + * Start the conversions. + */ + i2c_smbus_write_byte_data(client, ADT7481_REG_W_CONVRATE, + 5); /* 2 Hz */ + if (adt7481_read_reg(client, ADT7481_REG_R_CONFIG1, &config) < 0) { + dev_warn(&client->dev, "Initialization failed!\n"); + return; + } + config_orig = config; + + /* Check Temperature Range Select */ + if (config & 0x04) + data->flags |= ADT7481_FLAG_ADT7461_EXT; + + config &= 0xBF; /* run */ + if (config != config_orig) /* Only write if changed */ + i2c_smbus_write_byte_data(client, ADT7481_REG_W_CONFIG1, + config); +} + +static int adt7481_remove(struct i2c_client *client) +{ + struct adt7481_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &adt7481_group); + device_remove_file(&client->dev, &dev_attr_pec); + kfree(data); + return 0; +} + +static int adt7481_read16(struct i2c_client *client, u8 regh, u8 regl, + u16 *value) +{ + int err; + u8 oldh, newh, l; + + /* + * There is a trick here. We have to read two registers to have the + * sensor temperature, but we have to beware a conversion could occur + * inbetween the readings. The datasheet says we should either use + * the one-shot conversion register, which we don't want to do + * (disables hardware monitoring) or monitor the busy bit, which is + * impossible (we can't read the values and monitor that bit at the + * exact same time). So the solution used here is to read the high + * byte once, then the low byte, then the high byte again. If the new + * high byte matches the old one, then we have a valid reading. Else + * we have to read the low byte again, and now we believe we have a + * correct reading. + */ + err = adt7481_read_reg(client, regh, &oldh); + if (err) + return err; + + err = adt7481_read_reg(client, regl, &l); + if (err) + return err; + err = adt7481_read_reg(client, regh, &newh); + if (err) + return err; + if (oldh != newh) { + err = adt7481_read_reg(client, regl, &l); + if (err) + return err; + } + *value = (newh << 8) | l; + + return 0; +} + +static struct adt7481_data *adt7481_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7481_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + u8 h; + + dev_dbg(&client->dev, "Updating adt7481 data.\n"); + adt7481_read_reg(client, ADT7481_REG_R_LOCAL_LOW, + &data->temp8[0]); + adt7481_read_reg(client, ADT7481_REG_R_LOCAL_HIGH, + &data->temp8[1]); + adt7481_read_reg(client, ADT7481_REG_R_LOCAL_CRIT, + &data->temp8[2]); + adt7481_read_reg(client, ADT7481_REG_R_REMOTE1_CRIT, + &data->temp8[3]); + adt7481_read_reg(client, ADT7481_REG_R_REMOTE2_CRIT, + &data->temp8[4]); + adt7481_read_reg(client, ADT7481_REG_R_TCRIT_HYST, + &data->temp_hyst); + + if (adt7481_read_reg(client, ADT7481_REG_R_LOCAL_TEMP, &h) == 0) + data->temp11[8] = h << 8; + + adt7481_read16(client, ADT7481_REG_R_REMOTE1_TEMPH, + ADT7481_REG_R_REMOTE1_TEMPL, &data->temp11[0]); + adt7481_read16(client, ADT7481_REG_R_REMOTE2_TEMPH, + ADT7481_REG_R_REMOTE2_TEMPL, &data->temp11[4]); + adt7481_read16(client, ADT7481_REG_R_REMOTE1_LOWH, + ADT7481_REG_R_REMOTE1_LOWL, &data->temp11[1]); + adt7481_read16(client, ADT7481_REG_R_REMOTE2_LOWH, + ADT7481_REG_R_REMOTE2_LOWL, &data->temp11[5]); + adt7481_read16(client, ADT7481_REG_R_REMOTE1_HIGHH, + ADT7481_REG_R_REMOTE1_HIGHL, &data->temp11[2]); + adt7481_read16(client, ADT7481_REG_R_REMOTE2_HIGHH, + ADT7481_REG_R_REMOTE2_HIGHL, &data->temp11[6]); + adt7481_read16(client, ADT7481_REG_R_REMOTE1_OFFSH, + ADT7481_REG_R_REMOTE1_OFFSL, &data->temp11[3]); + adt7481_read16(client, ADT7481_REG_R_REMOTE2_OFFSH, + ADT7481_REG_R_REMOTE2_OFFSL, &data->temp11[7]); + + + adt7481_read_reg(client, ADT7481_REG_R_STATUS, &data->alarms); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init sensors_adt7481_init(void) +{ + return i2c_add_driver(&adt7481_driver); +} + +static void __exit sensors_adt7481_exit(void) +{ + i2c_del_driver(&adt7481_driver); +} + +MODULE_AUTHOR("Malcolm Crossley <malcolm.crossley@ge.com>"); +MODULE_DESCRIPTION("ADT7481 driver"); +MODULE_LICENSE("GPL"); + +module_init(sensors_adt7481_init); +module_exit(sensors_adt7481_exit); [-- Attachment #3: Type: text/plain, Size: 153 bytes --] _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors ^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2013-09-10 7:26 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-01-12 12:18 [lm-sensors] Supporting ADT7481 temperature sensor 2009-01-12 18:49 ` Hans de Goede 2009-01-14 10:29 ` Jean Delvare 2009-01-14 11:50 ` 2009-01-14 14:55 ` Jean Delvare 2012-10-12 10:30 ` Jia Hongtao-B38951 2012-10-12 13:18 ` Tabi Timur-B04825 2012-10-12 15:58 ` Jean Delvare 2012-10-15 2:21 ` Jia Hongtao-B38951 2012-10-15 2:22 ` Jia Hongtao-B38951 2013-08-30 12:04 ` Mercier Ivan 2013-08-30 16:21 ` Guenter Roeck 2013-08-31 12:56 ` Jean Delvare 2013-08-31 13:51 ` Guenter Roeck 2013-09-03 11:00 ` Mercier Ivan 2013-09-10 7:26 ` Jean Delvare
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.