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