Release 4.12 drivers/char/ds1620.c
  
  
  
/*
 * linux/drivers/char/ds1620.c: Dallas Semiconductors DS1620
 *   thermometer driver (as used in the Rebel.com NetWinder)
 */
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/capability.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <linux/uaccess.h>
#include <asm/therm.h>
#ifdef CONFIG_PROC_FS
/* define for /proc interface */
#define THERM_USE_PROC
#endif
/* Definitions for DS1620 chip */
#define THERM_START_CONVERT	0xee
#define THERM_RESET		0xaf
#define THERM_READ_CONFIG	0xac
#define THERM_READ_TEMP		0xaa
#define THERM_READ_TL		0xa2
#define THERM_READ_TH		0xa1
#define THERM_WRITE_CONFIG	0x0c
#define THERM_WRITE_TL		0x02
#define THERM_WRITE_TH		0x01
#define CFG_CPU			2
#define CFG_1SHOT		1
static DEFINE_MUTEX(ds1620_mutex);
static const char *fan_state[] = { "off", "on", "on (hardwired)" };
/*
 * Start of NetWinder specifics
 *  Note!  We have to hold the gpio lock with IRQs disabled over the
 *  whole of our transaction to the Dallas chip, since there is a
 *  chance that the WaveArtist driver could touch these bits to
 *  enable or disable the speaker.
 */
extern unsigned int system_rev;
static inline void netwinder_ds1620_set_clk(int clk)
{
	nw_gpio_modify_op(GPIO_DSCLK, clk ? GPIO_DSCLK : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 20 | 95.24% | 1 | 50.00% | 
| Russell King | 1 | 4.76% | 1 | 50.00% | 
| Total | 21 | 100.00% | 2 | 100.00% | 
static inline void netwinder_ds1620_set_data(int dat)
{
	nw_gpio_modify_op(GPIO_DATA, dat ? GPIO_DATA : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 20 | 95.24% | 1 | 50.00% | 
| Russell King | 1 | 4.76% | 1 | 50.00% | 
| Total | 21 | 100.00% | 2 | 100.00% | 
static inline int netwinder_ds1620_get_data(void)
{
	return nw_gpio_read() & GPIO_DATA;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 14 | 93.33% | 1 | 50.00% | 
| Russell King | 1 | 6.67% | 1 | 50.00% | 
| Total | 15 | 100.00% | 2 | 100.00% | 
static inline void netwinder_ds1620_set_data_dir(int dir)
{
	nw_gpio_modify_io(GPIO_DATA, dir ? GPIO_DATA : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 20 | 95.24% | 1 | 50.00% | 
| Russell King | 1 | 4.76% | 1 | 50.00% | 
| Total | 21 | 100.00% | 2 | 100.00% | 
static inline void netwinder_ds1620_reset(void)
{
	nw_cpld_modify(CPLD_DS_ENABLE, 0);
	nw_cpld_modify(CPLD_DS_ENABLE, CPLD_DS_ENABLE);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 21 | 91.30% | 1 | 50.00% | 
| Russell King | 2 | 8.70% | 1 | 50.00% | 
| Total | 23 | 100.00% | 2 | 100.00% | 
static inline void netwinder_lock(unsigned long *flags)
{
	raw_spin_lock_irqsave(&nw_gpio_lock, *flags);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 19 | 90.48% | 1 | 33.33% | 
| Arnd Bergmann | 1 | 4.76% | 1 | 33.33% | 
| Russell King | 1 | 4.76% | 1 | 33.33% | 
| Total | 21 | 100.00% | 3 | 100.00% | 
static inline void netwinder_unlock(unsigned long *flags)
{
	raw_spin_unlock_irqrestore(&nw_gpio_lock, *flags);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 19 | 90.48% | 1 | 33.33% | 
| Russell King | 1 | 4.76% | 1 | 33.33% | 
| Arnd Bergmann | 1 | 4.76% | 1 | 33.33% | 
| Total | 21 | 100.00% | 3 | 100.00% | 
static inline void netwinder_set_fan(int i)
{
	unsigned long flags;
	raw_spin_lock_irqsave(&nw_gpio_lock, flags);
	nw_gpio_modify_op(GPIO_FAN, i ? GPIO_FAN : 0);
	raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 36 | 87.80% | 1 | 33.33% | 
| Russell King | 3 | 7.32% | 1 | 33.33% | 
| Arnd Bergmann | 2 | 4.88% | 1 | 33.33% | 
| Total | 41 | 100.00% | 3 | 100.00% | 
static inline int netwinder_get_fan(void)
{
	if ((system_rev & 0xf000) == 0x4000)
		return FAN_ALWAYS_ON;
	return (nw_gpio_read() & GPIO_FAN) ? FAN_ON : FAN_OFF;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 33 | 97.06% | 1 | 50.00% | 
| Russell King | 1 | 2.94% | 1 | 50.00% | 
| Total | 34 | 100.00% | 2 | 100.00% | 
/*
 * End of NetWinder specifics
 */
static void ds1620_send_bits(int nr, int value)
{
	int i;
	for (i = 0; i < nr; i++) {
		netwinder_ds1620_set_data(value & 1);
		netwinder_ds1620_set_clk(0);
		udelay(1);
		netwinder_ds1620_set_clk(1);
		udelay(1);
		value >>= 1;
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 61 | 100.00% | 1 | 100.00% | 
| Total | 61 | 100.00% | 1 | 100.00% | 
static unsigned int ds1620_recv_bits(int nr)
{
	unsigned int value = 0, mask = 1;
	int i;
	netwinder_ds1620_set_data(0);
	for (i = 0; i < nr; i++) {
		netwinder_ds1620_set_clk(0);
		udelay(1);
		if (netwinder_ds1620_get_data())
			value |= mask;
		mask <<= 1;
		netwinder_ds1620_set_clk(1);
		udelay(1);
	}
	return value;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 79 | 100.00% | 1 | 100.00% | 
| Total | 79 | 100.00% | 1 | 100.00% | 
static void ds1620_out(int cmd, int bits, int value)
{
	unsigned long flags;
	netwinder_lock(&flags);
	netwinder_ds1620_set_clk(1);
	netwinder_ds1620_set_data_dir(0);
	netwinder_ds1620_reset();
	udelay(1);
	ds1620_send_bits(8, cmd);
	if (bits)
		ds1620_send_bits(bits, value);
	udelay(1);
	netwinder_ds1620_reset();
	netwinder_unlock(&flags);
	msleep(20);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 78 | 97.50% | 1 | 50.00% | 
| Domen Puncer | 2 | 2.50% | 1 | 50.00% | 
| Total | 80 | 100.00% | 2 | 100.00% | 
static unsigned int ds1620_in(int cmd, int bits)
{
	unsigned long flags;
	unsigned int value;
	netwinder_lock(&flags);
	netwinder_ds1620_set_clk(1);
	netwinder_ds1620_set_data_dir(0);
	netwinder_ds1620_reset();
	udelay(1);
	ds1620_send_bits(8, cmd);
	netwinder_ds1620_set_data_dir(1);
	value = ds1620_recv_bits(bits);
	netwinder_ds1620_reset();
	netwinder_unlock(&flags);
	return value;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 76 | 100.00% | 1 | 100.00% | 
| Total | 76 | 100.00% | 1 | 100.00% | 
static int cvt_9_to_int(unsigned int val)
{
	if (val & 0x100)
		val |= 0xfffffe00;
	return val;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 23 | 100.00% | 1 | 100.00% | 
| Total | 23 | 100.00% | 1 | 100.00% | 
static void ds1620_write_state(struct therm *therm)
{
	ds1620_out(THERM_WRITE_CONFIG, 8, CFG_CPU);
	ds1620_out(THERM_WRITE_TL, 9, therm->lo);
	ds1620_out(THERM_WRITE_TH, 9, therm->hi);
	ds1620_out(THERM_START_CONVERT, 0, 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 51 | 100.00% | 1 | 100.00% | 
| Total | 51 | 100.00% | 1 | 100.00% | 
static void ds1620_read_state(struct therm *therm)
{
	therm->lo = cvt_9_to_int(ds1620_in(THERM_READ_TL, 9));
	therm->hi = cvt_9_to_int(ds1620_in(THERM_READ_TH, 9));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 39 | 100.00% | 1 | 100.00% | 
| Total | 39 | 100.00% | 1 | 100.00% | 
static int ds1620_open(struct inode *inode, struct file *file)
{
	return nonseekable_open(inode, file);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Arnd Bergmann | 24 | 100.00% | 1 | 100.00% | 
| Total | 24 | 100.00% | 1 | 100.00% | 
static ssize_t
ds1620_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
{
	signed int cur_temp;
	signed char cur_temp_degF;
	cur_temp = cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9)) >> 1;
	/* convert to Fahrenheit, as per wdt.c */
	cur_temp_degF = (cur_temp * 9) / 5 + 32;
	if (copy_to_user(buf, &cur_temp_degF, 1))
		return -EFAULT;
	return 1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 76 | 98.70% | 1 | 50.00% | 
| Russell King | 1 | 1.30% | 1 | 50.00% | 
| Total | 77 | 100.00% | 2 | 100.00% | 
static int
ds1620_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct therm therm;
	union {
		struct therm __user *therm;
		int __user *i;
	} uarg;
	int i;
	uarg.i = (int __user *)arg;
	switch(cmd) {
	case CMD_SET_THERMOSTATE:
	case CMD_SET_THERMOSTATE2:
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
		if (cmd == CMD_SET_THERMOSTATE) {
			if (get_user(therm.hi, uarg.i))
				return -EFAULT;
			therm.lo = therm.hi - 3;
		} else {
			if (copy_from_user(&therm, uarg.therm, sizeof(therm)))
				return -EFAULT;
		}
		therm.lo <<= 1;
		therm.hi <<= 1;
		ds1620_write_state(&therm);
		break;
	case CMD_GET_THERMOSTATE:
	case CMD_GET_THERMOSTATE2:
		ds1620_read_state(&therm);
		therm.lo >>= 1;
		therm.hi >>= 1;
		if (cmd == CMD_GET_THERMOSTATE) {
			if (put_user(therm.hi, uarg.i))
				return -EFAULT;
		} else {
			if (copy_to_user(uarg.therm, &therm, sizeof(therm)))
				return -EFAULT;
		}
		break;
	case CMD_GET_TEMPERATURE:
	case CMD_GET_TEMPERATURE2:
		i = cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9));
		if (cmd == CMD_GET_TEMPERATURE)
			i >>= 1;
		return put_user(i, uarg.i) ? -EFAULT : 0;
	case CMD_GET_STATUS:
		i = ds1620_in(THERM_READ_CONFIG, 8) & 0xe3;
		return put_user(i, uarg.i) ? -EFAULT : 0;
	case CMD_GET_FAN:
		i = netwinder_get_fan();
		return put_user(i, uarg.i) ? -EFAULT : 0;
	case CMD_SET_FAN:
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
		if (get_user(i, uarg.i))
			return -EFAULT;
		netwinder_set_fan(i);
		break;
		
	default:
		return -ENOIOCTLCMD;
	}
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 317 | 86.14% | 1 | 50.00% | 
| Russell King | 51 | 13.86% | 1 | 50.00% | 
| Total | 368 | 100.00% | 2 | 100.00% | 
static long
ds1620_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret;
	mutex_lock(&ds1620_mutex);
	ret = ds1620_ioctl(file, cmd, arg);
	mutex_unlock(&ds1620_mutex);
	return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Arnd Bergmann | 48 | 100.00% | 2 | 100.00% | 
| Total | 48 | 100.00% | 2 | 100.00% | 
#ifdef THERM_USE_PROC
static int ds1620_proc_therm_show(struct seq_file *m, void *v)
{
	struct therm th;
	int temp;
	ds1620_read_state(&th);
	temp =  cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9));
	seq_printf(m, "Thermostat: HI %i.%i, LOW %i.%i; temperature: %i.%i C, fan %s\n",
		   th.hi >> 1, th.hi & 1 ? 5 : 0,
		   th.lo >> 1, th.lo & 1 ? 5 : 0,
		   temp  >> 1, temp  & 1 ? 5 : 0,
		   fan_state[netwinder_get_fan()]);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 91 | 91.00% | 1 | 50.00% | 
| David Howells | 9 | 9.00% | 1 | 50.00% | 
| Total | 100 | 100.00% | 2 | 100.00% | 
static int ds1620_proc_therm_open(struct inode *inode, struct file *file)
{
	return single_open(file, ds1620_proc_therm_show, NULL);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| David Howells | 23 | 88.46% | 1 | 50.00% | 
| Linus Torvalds (pre-git) | 3 | 11.54% | 1 | 50.00% | 
| Total | 26 | 100.00% | 2 | 100.00% | 
static const struct file_operations ds1620_proc_therm_fops = {
	.open		= ds1620_proc_therm_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
#endif
static const struct file_operations ds1620_fops = {
	.owner		= THIS_MODULE,
	.open		= ds1620_open,
	.read		= ds1620_read,
	.unlocked_ioctl	= ds1620_unlocked_ioctl,
	.llseek		= no_llseek,
};
static struct miscdevice ds1620_miscdev = {
	TEMP_MINOR,
	"temp",
	&ds1620_fops
};
static int __init ds1620_init(void)
{
	int ret;
	struct therm th, th_start;
	if (!machine_is_netwinder())
		return -ENODEV;
	ds1620_out(THERM_RESET, 0, 0);
	ds1620_out(THERM_WRITE_CONFIG, 8, CFG_CPU);
	ds1620_out(THERM_START_CONVERT, 0, 0);
	/*
         * Trigger the fan to start by setting
         * temperature high point low.  This kicks
         * the fan into action.
         */
	ds1620_read_state(&th);
	th_start.lo = 0;
	th_start.hi = 1;
	ds1620_write_state(&th_start);
	msleep(2000);
	ds1620_write_state(&th);
	ret = misc_register(&ds1620_miscdev);
	if (ret < 0)
		return ret;
#ifdef THERM_USE_PROC
	if (!proc_create("therm", 0, NULL, &ds1620_proc_therm_fops))
		printk(KERN_ERR "therm: unable to register /proc/therm\n");
#endif
	ds1620_read_state(&th);
	ret = cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9));
	printk(KERN_INFO "Thermostat: high %i.%i, low %i.%i, "
	       "current %i.%i C, fan %s.\n",
	       th.hi >> 1, th.hi & 1 ? 5 : 0,
	       th.lo >> 1, th.lo & 1 ? 5 : 0,
	       ret   >> 1, ret   & 1 ? 5 : 0,
	       fan_state[netwinder_get_fan()]);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 201 | 94.81% | 1 | 16.67% | 
| David Howells | 6 | 2.83% | 1 | 16.67% | 
| Maximilian Attems | 2 | 0.94% | 1 | 16.67% | 
| Russell King | 2 | 0.94% | 2 | 33.33% | 
| Al Viro | 1 | 0.47% | 1 | 16.67% | 
| Total | 212 | 100.00% | 6 | 100.00% | 
static void __exit ds1620_exit(void)
{
#ifdef THERM_USE_PROC
	remove_proc_entry("therm", NULL);
#endif
	misc_deregister(&ds1620_miscdev);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 26 | 96.30% | 1 | 50.00% | 
| Russell King | 1 | 3.70% | 1 | 50.00% | 
| Total | 27 | 100.00% | 2 | 100.00% | 
module_init(ds1620_init);
module_exit(ds1620_exit);
MODULE_LICENSE("GPL");
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Linus Torvalds (pre-git) | 1472 | 85.43% | 4 | 17.39% | 
| Arnd Bergmann | 93 | 5.40% | 5 | 21.74% | 
| Russell King | 68 | 3.95% | 4 | 17.39% | 
| David Howells | 67 | 3.89% | 1 | 4.35% | 
| Linus Torvalds | 10 | 0.58% | 3 | 13.04% | 
| Art Haas | 6 | 0.35% | 1 | 4.35% | 
| Al Viro | 2 | 0.12% | 2 | 8.70% | 
| Maximilian Attems | 2 | 0.12% | 1 | 4.35% | 
| Domen Puncer | 2 | 0.12% | 1 | 4.35% | 
| Arjan van de Ven | 1 | 0.06% | 1 | 4.35% | 
| Total | 1723 | 100.00% | 23 | 100.00% | 
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.