Ds1722.c

From Compulab Mediawiki
Jump to: navigation, search

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