Ds1722.c
This is a sample driver module for Dallas Semiconductor Digital Thermometer DS1722:
#include <linux/hwmon.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/spi/spi.h>
#include <linux/delay.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa2xx_spi.h>
/* defining another CE pin: sb270 p16 pin 45 */
#define DS1722_FRAME_GPIO 107
/* ds1722 CE Inactive time is 400ns - sleeping for 1ms */
#define CE_WAIT_MSEC 1
extern int pxa_gpio_mode(int);
extern void pxa_gpio_set_value(unsigned gpio, int value);
extern int gpio_direction_output(unsigned gpio, int value);
static int set_pxa_spi_gpio_config(void)
{
int modes_num = 4, ret = 0, i = 0;
int mode[] = { GPIO23_SCLK_MD,
GPIO24_SFRM_MD,
GPIO25_STXD_MD,
GPIO26_SRXD_MD };
for (i = 0; i < modes_num; i++)
if ((ret = pxa_gpio_mode(mode[i])) != 0)
return ret;
/* setting up alternative gpio frame - CE */
return gpio_direction_output(DS1722_FRAME_GPIO, 0);
}
static int __devinit ds1722_probe(struct spi_device *spi)
{
int ret = 0;
u8 in[4] = { 0 };
/* Setup spi */
ret = spi_setup(spi);
in[0] = 0x80; in[1] = 0x00;
printk(KERN_INFO "\nWriting configuration to register:\t0x%x", in[0]);
mdelay(CE_WAIT_MSEC);
pxa_gpio_set_value(DS1722_FRAME_GPIO, 1); /* Set CE HIGH */
ret = spi_write(spi,in,2);
pxa_gpio_set_value(DS1722_FRAME_GPIO, 0); /* Set CE LOW */
printk(KERN_INFO "\n%s:\tin\t=\t\t0x%x,0x%x", "spi_write", in[0], in[1]);
printk(KERN_INFO "\n%s: returned\t\t\t%d\n", "spi_write", ret);
in[0] = 0x00; in[1] = 0x00;
printk(KERN_INFO "\nReading configuration from register:\t0x%x", in[0]);
mdelay(CE_WAIT_MSEC);
pxa_gpio_set_value(DS1722_FRAME_GPIO, 1); /* Set CE HIGH */
ret = spi_w8r8(spi,in[0]);
pxa_gpio_set_value(DS1722_FRAME_GPIO, 0); /* Set CE LOW */
printk(KERN_INFO "\n%s: returned\t\t\t0x%x\n", "spi_w8r8", ret);
in[0] = 0x02; in[1] = 0x00;
printk(KERN_INFO "\nReading temperature MSB from register:\t0x%x", in[0]);
mdelay(CE_WAIT_MSEC);
pxa_gpio_set_value(DS1722_FRAME_GPIO, 1); /* Set CE HIGH */
ret = spi_w8r8(spi,in[0]);
pxa_gpio_set_value(DS1722_FRAME_GPIO, 0); /* Set CE LOW */
printk(KERN_INFO "\n%s: returned\t\t\t%d\n", "spi_w8r8", ret);
in[0] = 0x01; in[1] = 0x00;
printk(KERN_INFO "\nReading temperature LSB from register:\t0x%x", in[0]);
mdelay(CE_WAIT_MSEC);
pxa_gpio_set_value(DS1722_FRAME_GPIO, 1); /* Set CE HIGH */
ret = spi_w8r8(spi,in[0]);
pxa_gpio_set_value(DS1722_FRAME_GPIO, 0); /* Set CE LOW */
printk(KERN_INFO "\n%s: returned\t\t\t%d\n", "spi_w8r8", ret);
return 0;
}
static int __devexit ds1722_remove(struct spi_device *spi)
{
return 0;
}
static struct spi_driver ds1722_driver = {
.driver = {
.name = "ds1722_spi",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = ds1722_probe,
.remove = __devexit_p(ds1722_remove),
};
static int __init ds1722_init(void)
{
int ret = set_pxa_spi_gpio_config();
if(ret < 0)
return ret;
return spi_register_driver(&ds1722_driver);
}
module_init(ds1722_init);
static void __exit ds1722_exit(void)
{
spi_unregister_driver(&ds1722_driver);
}
module_exit(ds1722_exit);
MODULE_DESCRIPTION("DS1722 SPI Thermometer Driver");
MODULE_LICENSE("GPL");
back to: SPI support for CM-X270