diff options
| author | Kaiwan N Billimoria <kaiwan@designergraphix.com> | 2009-01-07 10:37:34 -0500 |
|---|---|---|
| committer | Jean Delvare <khali@linux-fr.org> | 2009-01-07 10:37:34 -0500 |
| commit | 2b7300513b98e05058a803de3beb8a1c0a0c61d9 (patch) | |
| tree | 279b61da3b204e44bc52ad62a4836e28ffce1bde | |
| parent | 0589c2de643ef71a684ba6d219532f9e2a3e554b (diff) | |
hwmon: (lm70) Code streamlining and cleanup
This fixes a byteswap bug in the LM70 temperature sensor driver,
which was previously covered up by a converse bug in the driver
for the LM70EVAL-LLP board (which is also fixed).
Other fixes: doc updates, remove an annoying msleep(), and improve
three-wire protocol handling.
Signed-off-by: Kaiwan N Billimoria <kaiwan@designergraphix.com>
[ dbrownell@users.sourceforge.net: doc and whitespace tweaks ]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
| -rw-r--r-- | Documentation/hwmon/lm70 | 4 | ||||
| -rw-r--r-- | Documentation/spi/spi-lm70llp | 10 | ||||
| -rw-r--r-- | drivers/hwmon/lm70.c | 9 | ||||
| -rw-r--r-- | drivers/spi/spi_lm70llp.c | 33 |
4 files changed, 31 insertions, 25 deletions
diff --git a/Documentation/hwmon/lm70 b/Documentation/hwmon/lm70 index 2bdd3feebf53..b8d1a521e689 100644 --- a/Documentation/hwmon/lm70 +++ b/Documentation/hwmon/lm70 | |||
| @@ -25,6 +25,10 @@ complement digital temperature (sent via the SIO line), is available in the | |||
| 25 | driver for interpretation. This driver makes use of the kernel's in-core | 25 | driver for interpretation. This driver makes use of the kernel's in-core |
| 26 | SPI support. | 26 | SPI support. |
| 27 | 27 | ||
| 28 | As a real (in-tree) example of this "SPI protocol driver" interfacing | ||
| 29 | with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c | ||
| 30 | and its associated documentation. | ||
| 31 | |||
| 28 | Thanks to | 32 | Thanks to |
| 29 | --------- | 33 | --------- |
| 30 | Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver | 34 | Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver |
diff --git a/Documentation/spi/spi-lm70llp b/Documentation/spi/spi-lm70llp index 154bd02220b9..34a9cfd746bd 100644 --- a/Documentation/spi/spi-lm70llp +++ b/Documentation/spi/spi-lm70llp | |||
| @@ -13,10 +13,20 @@ Description | |||
| 13 | This driver provides glue code connecting a National Semiconductor LM70 LLP | 13 | This driver provides glue code connecting a National Semiconductor LM70 LLP |
| 14 | temperature sensor evaluation board to the kernel's SPI core subsystem. | 14 | temperature sensor evaluation board to the kernel's SPI core subsystem. |
| 15 | 15 | ||
| 16 | This is a SPI master controller driver. It can be used in conjunction with | ||
| 17 | (layered under) the LM70 logical driver (a "SPI protocol driver"). | ||
| 16 | In effect, this driver turns the parallel port interface on the eval board | 18 | In effect, this driver turns the parallel port interface on the eval board |
| 17 | into a SPI bus with a single device, which will be driven by the generic | 19 | into a SPI bus with a single device, which will be driven by the generic |
| 18 | LM70 driver (drivers/hwmon/lm70.c). | 20 | LM70 driver (drivers/hwmon/lm70.c). |
| 19 | 21 | ||
| 22 | |||
| 23 | Hardware Interfacing | ||
| 24 | -------------------- | ||
| 25 | The schematic for this particular board (the LM70EVAL-LLP) is | ||
| 26 | available (on page 4) here: | ||
| 27 | |||
| 28 | http://www.national.com/appinfo/tempsensors/files/LM70LLPEVALmanual.pdf | ||
| 29 | |||
| 20 | The hardware interfacing on the LM70 LLP eval board is as follows: | 30 | The hardware interfacing on the LM70 LLP eval board is as follows: |
| 21 | 31 | ||
| 22 | Parallel LM70 LLP | 32 | Parallel LM70 LLP |
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index d435f003292d..9f9741b1d2b5 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c | |||
| @@ -65,10 +65,9 @@ static ssize_t lm70_sense_temp(struct device *dev, | |||
| 65 | "spi_write_then_read failed with status %d\n", status); | 65 | "spi_write_then_read failed with status %d\n", status); |
| 66 | goto out; | 66 | goto out; |
| 67 | } | 67 | } |
| 68 | dev_dbg(dev, "rxbuf[1] : 0x%x rxbuf[0] : 0x%x\n", rxbuf[1], rxbuf[0]); | 68 | raw = (rxbuf[0] << 8) + rxbuf[1]; |
| 69 | 69 | dev_dbg(dev, "rxbuf[0] : 0x%02x rxbuf[1] : 0x%02x raw=0x%04x\n", | |
| 70 | raw = (rxbuf[1] << 8) + rxbuf[0]; | 70 | rxbuf[0], rxbuf[1], raw); |
| 71 | dev_dbg(dev, "raw=0x%x\n", raw); | ||
| 72 | 71 | ||
| 73 | /* | 72 | /* |
| 74 | * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's | 73 | * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's |
| @@ -109,6 +108,8 @@ static int __devinit lm70_probe(struct spi_device *spi) | |||
| 109 | if ((spi->mode & (SPI_CPOL|SPI_CPHA)) || !(spi->mode & SPI_3WIRE)) | 108 | if ((spi->mode & (SPI_CPOL|SPI_CPHA)) || !(spi->mode & SPI_3WIRE)) |
| 110 | return -EINVAL; | 109 | return -EINVAL; |
| 111 | 110 | ||
| 111 | /* NOTE: we assume 8-bit words, and convert to 16 bits manually */ | ||
| 112 | |||
| 112 | p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL); | 113 | p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL); |
| 113 | if (!p_lm70) | 114 | if (!p_lm70) |
| 114 | return -ENOMEM; | 115 | return -ENOMEM; |
diff --git a/drivers/spi/spi_lm70llp.c b/drivers/spi/spi_lm70llp.c index af6526767e2a..568c781ad91c 100644 --- a/drivers/spi/spi_lm70llp.c +++ b/drivers/spi/spi_lm70llp.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * spi_lm70llp.c - driver for lm70llp eval board for the LM70 sensor | 2 | * spi_lm70llp.c - driver for LM70EVAL-LLP board for the LM70 sensor |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2006 Kaiwan N Billimoria <kaiwan@designergraphix.com> | 4 | * Copyright (C) 2006 Kaiwan N Billimoria <kaiwan@designergraphix.com> |
| 5 | * | 5 | * |
| @@ -40,8 +40,12 @@ | |||
| 40 | * master controller driver. The hwmon/lm70 driver is a "SPI protocol | 40 | * master controller driver. The hwmon/lm70 driver is a "SPI protocol |
| 41 | * driver", layered on top of this one and usable without the lm70llp. | 41 | * driver", layered on top of this one and usable without the lm70llp. |
| 42 | * | 42 | * |
| 43 | * Datasheet and Schematic: | ||
| 43 | * The LM70 is a temperature sensor chip from National Semiconductor; its | 44 | * The LM70 is a temperature sensor chip from National Semiconductor; its |
| 44 | * datasheet is available at http://www.national.com/pf/LM/LM70.html | 45 | * datasheet is available at http://www.national.com/pf/LM/LM70.html |
| 46 | * The schematic for this particular board (the LM70EVAL-LLP) is | ||
| 47 | * available (on page 4) here: | ||
| 48 | * http://www.national.com/appinfo/tempsensors/files/LM70LLPEVALmanual.pdf | ||
| 45 | * | 49 | * |
| 46 | * Also see Documentation/spi/spi-lm70llp. The SPI<->parport code here is | 50 | * Also see Documentation/spi/spi-lm70llp. The SPI<->parport code here is |
| 47 | * (heavily) based on spi-butterfly by David Brownell. | 51 | * (heavily) based on spi-butterfly by David Brownell. |
| @@ -64,7 +68,7 @@ | |||
| 64 | * | 68 | * |
| 65 | * Note that parport pin 13 actually gets inverted by the transistor | 69 | * Note that parport pin 13 actually gets inverted by the transistor |
| 66 | * arrangement which lets either the parport or the LM70 drive the | 70 | * arrangement which lets either the parport or the LM70 drive the |
| 67 | * SI/SO signal. | 71 | * SI/SO signal (see the schematic for details). |
| 68 | */ | 72 | */ |
| 69 | 73 | ||
| 70 | #define DRVNAME "spi-lm70llp" | 74 | #define DRVNAME "spi-lm70llp" |
| @@ -106,12 +110,16 @@ static inline struct spi_lm70llp *spidev_to_pp(struct spi_device *spi) | |||
| 106 | static inline void deassertCS(struct spi_lm70llp *pp) | 110 | static inline void deassertCS(struct spi_lm70llp *pp) |
| 107 | { | 111 | { |
| 108 | u8 data = parport_read_data(pp->port); | 112 | u8 data = parport_read_data(pp->port); |
| 113 | |||
| 114 | data &= ~0x80; /* pull D7/SI-out low while de-asserted */ | ||
| 109 | parport_write_data(pp->port, data | nCS); | 115 | parport_write_data(pp->port, data | nCS); |
| 110 | } | 116 | } |
| 111 | 117 | ||
| 112 | static inline void assertCS(struct spi_lm70llp *pp) | 118 | static inline void assertCS(struct spi_lm70llp *pp) |
| 113 | { | 119 | { |
| 114 | u8 data = parport_read_data(pp->port); | 120 | u8 data = parport_read_data(pp->port); |
| 121 | |||
| 122 | data |= 0x80; /* pull D7/SI-out high so lm70 drives SO-in */ | ||
| 115 | parport_write_data(pp->port, data & ~nCS); | 123 | parport_write_data(pp->port, data & ~nCS); |
| 116 | } | 124 | } |
| 117 | 125 | ||
| @@ -184,22 +192,7 @@ static void lm70_chipselect(struct spi_device *spi, int value) | |||
| 184 | */ | 192 | */ |
| 185 | static u32 lm70_txrx(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits) | 193 | static u32 lm70_txrx(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits) |
| 186 | { | 194 | { |
| 187 | static u32 sio=0; | 195 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); |
| 188 | static int first_time=1; | ||
| 189 | |||
| 190 | /* First time: perform SPI bitbang and return the LSB of | ||
| 191 | * the result of the SPI call. | ||
| 192 | */ | ||
| 193 | if (first_time) { | ||
| 194 | sio = bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); | ||
| 195 | first_time=0; | ||
| 196 | return (sio & 0x00ff); | ||
| 197 | } | ||
| 198 | /* Return the MSB of the result of the SPI call */ | ||
| 199 | else { | ||
| 200 | first_time=1; | ||
| 201 | return (sio >> 8); | ||
| 202 | } | ||
| 203 | } | 196 | } |
| 204 | 197 | ||
| 205 | static void spi_lm70llp_attach(struct parport *p) | 198 | static void spi_lm70llp_attach(struct parport *p) |
| @@ -293,10 +286,9 @@ static void spi_lm70llp_attach(struct parport *p) | |||
| 293 | status = -ENODEV; | 286 | status = -ENODEV; |
| 294 | goto out_bitbang_stop; | 287 | goto out_bitbang_stop; |
| 295 | } | 288 | } |
| 296 | pp->spidev_lm70->bits_per_word = 16; | 289 | pp->spidev_lm70->bits_per_word = 8; |
| 297 | 290 | ||
| 298 | lm70llp = pp; | 291 | lm70llp = pp; |
| 299 | |||
| 300 | return; | 292 | return; |
| 301 | 293 | ||
| 302 | out_bitbang_stop: | 294 | out_bitbang_stop: |
| @@ -326,7 +318,6 @@ static void spi_lm70llp_detach(struct parport *p) | |||
| 326 | 318 | ||
| 327 | /* power down */ | 319 | /* power down */ |
| 328 | parport_write_data(pp->port, 0); | 320 | parport_write_data(pp->port, 0); |
| 329 | msleep(10); | ||
| 330 | 321 | ||
| 331 | parport_release(pp->pd); | 322 | parport_release(pp->pd); |
| 332 | parport_unregister_device(pp->pd); | 323 | parport_unregister_device(pp->pd); |
