Пример #1
0
static ssize_t cs5535_gpio_read(struct file *file, char __user *buf,
				size_t len, loff_t *ppos)
{
	u32	m = iminor(file->f_path.dentry->d_inode);
	u32	base = gpio_base + cs5535_lowhigh_base(m);
	int	rd_bit = 1 << (m & 0x0f);
	int	i;
	char	ch;
	ssize_t	count = 0;

	if (*ppos >= ARRAY_SIZE(rm))
		return 0;

	for (i = *ppos; (i < (*ppos + len)) && (i < ARRAY_SIZE(rm)); i++) {
		ch = (inl(base + rm[i].rd_offset) & rd_bit) ?
		     rm[i].on : rm[i].off;

		if (put_user(ch, buf+count))
			return -EFAULT;

		count++;
	}

	
	if ((i == ARRAY_SIZE(rm)) && (count < len)) {
		put_user('\n', buf + count);
		count++;
	}

	*ppos += count;
	return count;
}
Пример #2
0
static ssize_t cs5535_gpio_write(struct file *file, const char __user *data,
				 size_t len, loff_t *ppos)
{
	u32	m = iminor(file->f_path.dentry->d_inode);
	int	i, j;
	u32	base = gpio_base + cs5535_lowhigh_base(m);
	u32	m0, m1;
	char	c;

	
	m1 = 1 << (m & 0x0F);
	m0 = m1 << 16;

	for (i = 0; i < len; ++i) {
		if (get_user(c, data+i))
			return -EFAULT;

		for (j = 0; j < ARRAY_SIZE(rm); j++) {
			if (c == rm[j].on) {
				outl(m1, base + rm[j].wr_offset);
				
				if (c == 'O') {
					outl(m0, base + 0x10);
					outl(m0, base + 0x14);
				}
				break;
			} else if (c == rm[j].off) {
				outl(m0, base + rm[j].wr_offset);
				break;
			}
		}
	}
	*ppos = 0;
	return len;
}
Пример #3
0
static ssize_t cs5535_gpio_write(struct file *file, const char __user *data,
				 size_t len, loff_t *ppos)
{
	u32	m = iminor(file->f_path.dentry->d_inode);
	int	i, j;
	u32	base = gpio_base + cs5535_lowhigh_base(m);
	u32	m0, m1;
	char	c;

	/**
	 * Creates the mask for atomic bit programming.
	 * The high 16 bits and the low 16 bits are used to set the mask.
	 * For example, GPIO 15 maps to 31,15: 0,1 => On; 1,0=> Off
	 */
	m1 = 1 << (m & 0x0F);
	m0 = m1 << 16;

	for (i = 0; i < len; ++i) {
		if (get_user(c, data+i))
			return -EFAULT;

		for (j = 0; j < ARRAY_SIZE(rm); j++) {
			if (c == rm[j].on) {
				outl(m1, base + rm[j].wr_offset);
				break;
			} else if (c == rm[j].off) {
				outl(m0, base + rm[j].wr_offset);
				break;
			}
		}
	}
	*ppos = 0;
	return len;
}