📄 立宇泰嵌入式系统技术论坛-嵌入式操作系统相关-菜鸟写给菜鸟参考的44b0x_iic驱动程序.htm
字号:
style="COLOR: black; BACKGROUND-COLOR: #ffff66">44b0x</B>.h<BR><BR>*<BR><BR>* Sun
Jun 5 16:53:19
2005<BR><BR>* Copyright 2005 Yong F
Wang<BR><BR>* Email com_wang@21cn.com<BR><BR>****************************************************************************/<BR><BR><BR><BR>/*<BR><BR>* This
program is free software; you can redistribute it and/or
modify<BR><BR>* it under the terms of the GNU General
Public License as published by<BR><BR>* the Free Software
Foundation; either version 2 of the License,
or<BR><BR>* (at your option) any later
version.<BR><BR>*<BR><BR>* This program is distributed in
the hope that it will be useful,<BR><BR>* but WITHOUT ANY
WARRANTY; without even the implied warranty
of<BR><BR>* MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the<BR><BR>* GNU Library General
Public License for more details.<BR><BR>*<BR><BR>* You
should have received a copy of the GNU General Public
License<BR><BR>* along with this program; if not, write
to the Free Software<BR><BR>* Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307,
USA.<BR><BR>*/<BR><BR><BR><BR>#define U32 unsigned
int<BR><BR>#define S32 int<BR><BR>#define U16 short unsigned
int<BR><BR>#define S16 short int<BR><BR>#define U8 unsigned
char<BR><BR>#define S8 char<BR><BR><BR><BR>// <B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B> operation
mode define<BR><BR>#define <B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B>_RECEIVE 1<BR><BR>#define
<B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B>_TRANSMIT 2<BR><BR>#define
<B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B>_RD_ADDR 3<BR><BR><BR><BR>//
IOCTL operation definition<BR><BR>#define <B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B>_SLAVE_ADDR 15<BR><BR><BR><BR>#define
I2C_MAJOR 89<BR><BR>#define INT_I2C 5<BR><BR>DECLARE_WAIT_QUEUE_HEAD
(i2c_queue);<BR><BR><BR><BR>/*<BR><BR> i2c_<B
style="COLOR: black; BACKGROUND-COLOR: #ffff66">44b0x</B>.c - I2C
support for Samsung S3C<B
style="COLOR: black; BACKGROUND-COLOR: #ffff66">44B0X</B>, char
device interface<BR><BR><BR><BR> Copyright
(C) 2005 Yong F Wang
<com_wang@21cn.com><BR><BR><BR><BR> This
program is free software; you can redistribute it and/or
modify<BR><BR> it under the terms of the GNU
General Public License as published
by<BR><BR> the Free Software Foundation;
either version 2 of the License,
or<BR><BR> (at your option) any later
version.<BR><BR><BR><BR> This program is
distributed in the hope that it will be
useful,<BR><BR> but WITHOUT ANY WARRANTY;
without even the implied warranty
of<BR><BR> MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See
the<BR><BR> GNU General Public License for
more details.<BR><BR><BR><BR> You should have
received a copy of the GNU General Public
License<BR><BR> along with this program; if
not, write to the Free
Software<BR><BR> Foundation, Inc., 675 Mass
Ave, Cambridge, MA 02139, USA.<BR><BR>*/<BR><BR><BR><BR>/* $Id:
i2c_<B style="COLOR: black; BACKGROUND-COLOR: #ffff66">44b0x</B>.c,v
1.00 2005/06/05 11:28:01 mds Exp $ */<BR><BR><BR><BR>#include
<linux/fs.h><BR><BR>#include
<linux/init.h><BR><BR>#include
<linux/slab.h><BR><BR>#include
<linux/config.h><BR><BR>#include
<linux/kernel.h><BR><BR>#include
<linux/module.h><BR><BR>#include
<linux/version.h><BR><BR>#if LINUX_KERNEL_VERSION >=
KERNEL_VERSION(2,4,0)<BR><BR>#include
<linux/smp_lock.h><BR><BR>#endif<BR><BR>#ifdef
CONFIG_DEVFS_FS<BR><BR>#include
<linux/devfs_fs_kernel.h><BR><BR>#endif<BR><BR><BR><BR>#include
<asm/uaccess.h><BR><BR>#include
<asm/io.h><BR><BR>#include
<asm/system.h><BR><BR>#include
<asm/bitops.h><BR><BR>#include
<asm/hardware.h><BR><BR>#include "hardware.h"<BR><BR>#include
"i2c_<B
style="COLOR: black; BACKGROUND-COLOR: #ffff66">44b0x</B>.h"<BR><BR><BR><BR>#ifdef
MODULE<BR><BR>extern int init_module(void);<BR><BR>extern int
cleanup_module(void);<BR><BR>char
kernel_version[]=UTS_RELEASE;<BR><BR>#endif<BR><BR><BR><BR>//#define
DEBUG<BR><BR><BR><BR>/* struct file_operations changed too often in
the 2.1 series for nice code */<BR><BR>static ssize_t i2c_read
(struct file *file, char *buf, size_t count,
<BR><BR>
<BR>loff_t *offset);<BR><BR>static ssize_t i2c_write (struct file
*file, const char *buf, size_t count,
<BR><BR> <BR>loff_t
*offset);<BR><BR>static int i2c_ioctl (struct inode *inode, struct
file *file,
<BR><BR> <BR>unsigned
int cmd, unsigned long arg);<BR><BR>static int i2c_open (struct
inode *inode, struct file *file);<BR><BR>static int i2c_release
(struct inode *inode, struct file *file);<BR><BR><BR><BR>#ifdef
MODULE<BR><BR>static<BR><BR>#else<BR><BR>extern<BR><BR>#endif<BR><BR><BR><BR>int
__init init_i2c_<B
style="COLOR: black; BACKGROUND-COLOR: #ffff66">44b0x</B>(void);<BR><BR>static
int i2c_exit(void);<BR><BR>void i2c_irq_service(int irq,void
*dev_id,struct pt_regs *regs);<BR><BR><BR><BR>static struct
file_operations i2c_fops =
{<BR><BR> read: i2c_read,<BR><BR> write: i2c_write,<BR><BR> ioctl: i2c_ioctl,<BR><BR> open: i2c_open,<BR><BR> release: i2c_release,<BR><BR>};<BR><BR><BR><BR>static
int i2c_initialized,i2c_opened = 0;<BR><BR>static U32
PCONF_Backup,PUPF_Backup;<BR><BR>static U8
i2c_buf[64],i2c_buf_ptr,i2c_buf_count,i2c_oper_mode;<BR><BR><BR><BR>static
ssize_t i2c_read (struct file *file, char *buf, size_t
count,<BR><BR>
<BR>loff_t
*offset)<BR><BR>{<BR><BR> i2c_buf_ptr =
0;<BR><BR> i2c_buf_count =
count;<BR><BR> i2c_oper_mode = <B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B>_RD_ADDR;<BR><BR> IICSTAT
= 0xB0;<BR><BR> IICCON =
0xE0;<BR><BR> interruptible_sleep_on(&i2c_queue); //
sleep and wait receive finish<BR><BR> count =
i2c_buf_count;<BR><BR> if(copy_to_user(buf,
i2c_buf,
count))<BR><BR> {<BR><BR> printk("error
reading,
copy_to_user\n");<BR><BR> return
-EFAULT;<BR><BR> }<BR><BR> return
count;<BR><BR>}<BR><BR><BR><BR>static ssize_t i2c_write (struct file
*file, const char *buf, size_t
count,<BR><BR> <BR>loff_t
*offset)<BR><BR>{<BR><BR> if(copy_from_user(i2c_buf,
buf,
count))<BR><BR> {<BR><BR> printk("error
writing,
copy_from_user\n");<BR><BR> return
-EFAULT;<BR><BR> }<BR><BR> if(count
< 2) return -EFAULT;<BR><BR> i2c_buf_count
= count;<BR><BR> i2c_buf_ptr =
0;<BR><BR> i2c_oper_mode = <B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B>_TRANSMIT;<BR><BR> IICSTAT
=
0xF0; //
Master Transmit mode<BR><BR> IICCON =
0xE0; //
Clear panding bit<BR><BR>
<BR>interruptible_sleep_on(&i2c_queue);
<BR> // sleep and wait transmit
finish<BR><BR> count =
i2c_buf_ptr;<BR><BR> return
count;<BR><BR>}<BR><BR><BR><BR>static int i2c_ioctl (struct inode
*inode, struct file *file, unsigned int cmd,
<BR><BR> unsigned
long
arg)<BR><BR>{<BR><BR> switch(cmd)<BR><BR> {<BR><BR> case
<B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B>_SLAVE_ADDR:<BR><BR> IICDS
=
(U8)(arg<<1);<BR><BR> break;<BR><BR> default:<BR><BR> }<BR><BR> return
0;<BR><BR>}<BR><BR><BR><BR>static int i2c_open (struct inode *inode,
struct file
*file)<BR><BR>{<BR><BR> if(i2c_opened >=
1)<BR><BR> {<BR><BR> printk("I2C
device already
opened!\n");<BR><BR> return
-ENODEV;<BR><BR> }<BR><BR> PCONF_Backup
= PCONF; // Backup
PCONF<BR><BR> PCONF &=
0xFFFFFFF0;<BR><BR> PCONF |=
0x0A;
<BR> // Set GPF0 to I2C SCL, set GPF1 to I2C
SDA.<BR><BR> PUPF_Backup =
PUPF; // Backup
PUPF<BR><BR> PUPF |=
0x03;
<BR> // Disable pull up resistor of
GPF0&GPF1<BR><BR> IICSTAT =
0x10; //
Enable RX/TX<BR><BR> IICCON =
0xE0;<BR><BR> i2c_opened++;<BR><BR> return
0;<BR><BR>}<BR><BR><BR><BR>static int i2c_release (struct inode
*inode, struct file
*file)<BR><BR>{<BR><BR> if(i2c_opened <
1)<BR><BR> {<BR><BR> printk("I2C
device already
closed!\n");<BR><BR> }<BR><BR> PCONF
= PCONF_Backup; // Restore
PCONF<BR><BR> PUPF =
PUPF_Backup; //
Restore PUPF<BR><BR> IICSTAT =
0; //
Disable <B
style="COLOR: black; BACKGROUND-COLOR: #a0ffff">IIC</B><BR><BR> i2c_opened--;<BR><BR> return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -