#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include “io_595.h”
static dev_t hc595_devno;
static struct class *hc595_class;
static struct cdev *hc595_dev;
static uint32_t gpio_status = 0;
static int hc595_open (struct inode *inode, struct file *filep)
{
printk(“hc595_open \n”);
return 0;
}
static void hc595_send_bytes(uint32_t io_bytes)
{
uint8_t i;
gpio_set_value(GPIO_HC595_ST, 0);
for(i=0; i<24; i++)
{
gpio_set_value(GPIO_HC595_SH, 0);
if((io_bytes & 0x00800000) == 0x00800000)
{
printk(“Bit Loc:%d-%x\n”, 23-i, io_bytes & 0x00800000);
gpio_set_value(GPIO_HC595_DS, 1);
}
else
{
gpio_set_value(GPIO_HC595_DS, 0);
}
mdelay(2);
gpio_set_value(GPIO_HC595_SH, 1);
io_bytes = io_bytes << 1;
}
gpio_set_value(GPIO_HC595_ST, 1);
mdelay(2);
gpio_set_value(GPIO_HC595_ST, 0);
gpio_set_value(GPIO_HC595_OE, 0);
}
static ssize_t hc595_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
copy_from_user(&gpio_status, buf, 4); //拷贝4个字节
printk(“Write IO_Val:%d\n”, gpio_status);
hc595_send_bytes(gpio_status);
return 1;
}
static struct file_operations hc595_ops=
{
.open = hc595_open,
.write = hc595_write,
};
static int hc595_init(void)
{
int ret;
/*动态分配设备号/
ret = alloc_chrdev_region(&hc595_devno, 0, 1, “hc595_io”);
if(ret)
{
printk(“alloc_chrdev_region fail!\n”);
unregister_chrdev_region(hc595_devno,1);
return ret;
}
else
{
printk(“alloc_chrdev_region success!\n”);
}
/*描述结构初始化/
cdev_init(&hc595_dev, &hc595_ops);
/*描述结构注册/
ret = cdev_add(&hc595_dev, hc595_devno, 1);
if(ret)
{
printk(“cdev add fail.\n”);
unregister_chrdev_region(hc595_devno, 1);
return ret;
}
else
{
printk(“cdev add sucess!\n”);
}
hc595_class = class_create(THIS_MODULE,“hc595_class”);
if(IS_ERR(hc595_class))
{
printk(“Create class fail!\n”);
unregister_chrdev_region(hc595_devno,1);
return -1;
}
else
{
printk(“Create class sucess!\n”);
}
device_create(hc595_class,NULL,hc595_devno,0,“hc595”);
//申请GPIO
gpio_request(GPIO_HC595_ST, “GPIO_HC595_ST”);
gpio_direction_output(GPIO_HC595_ST, 1);
gpio_request(GPIO_HC595_SH, “GPIO_HC595_SH”);
gpio_direction_output(GPIO_HC595_SH, 1);
gpio_request(GPIO_HC595_DS, “GPIO_HC595_DS”);
gpio_direction_output(GPIO_HC595_DS, 1);
gpio_request(GPIO_HC595_OE, “GPIO_HC595_OE”);
gpio_direction_output(GPIO_HC595_OE, 0); //OE设置为低电平,使能状态
//所有端口设置低电平
hc595_send_bytes(0x00000000);
printk(“HC595_init…\n”);
return 0;
}
static void hc595_exit(void)
{
device_destroy(hc595_class,hc595_devno);
class_destroy(hc595_class);
cdev_del(&hc595_dev);
unregister_chrdev_region(hc595_devno,1);
printk(“hc595_exit…\n”);
}
MODULE_LICENSE(“GPL”);
module_init(hc595_init);
module_exit(hc595_exit);
头文件内容只定义了GPIO
#ifndef _IO_595_H
#define _IO_595_H
#define GPIO_HC595_DS GPIOB(3)
#define GPIO_HC595_ST GPIOB(4)
#define GPIO_HC595_SH GPIOB(6)
#define GPIO_HC595_OE GPIOB(13)
#endif