代码如下:
/*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
//#include <mach/io.h>
#include <linux/gpio.h>
/* define spi gpio*/
#define TXD_PORT 109
#define CLK_PORT 108
#define CS_PORT 111
#define RXD_PORT 110
#define SSD2828_RESET_PIN 39 // 51
#define INVALID_GPIO -1
#define GPIO_HIGH 1
#define GPIO_LOW 0
#define CS_OUT() gpio_direction_output(CS_PORT, 1)
#define CS_SET() gpio_set_value(CS_PORT, GPIO_HIGH)
#define CS_CLR() gpio_set_value(CS_PORT, GPIO_LOW)
#define CLK_OUT() gpio_direction_output(CLK_PORT, 1)
#define CLK_SET() gpio_set_value(CLK_PORT, GPIO_HIGH)
#define CLK_CLR() gpio_set_value(CLK_PORT, GPIO_LOW)
#define TXD_OUT() gpio_direction_output(TXD_PORT, 1)
#define TXD_SET() gpio_set_value(TXD_PORT, GPIO_HIGH)
#define TXD_CLR() gpio_set_value(TXD_PORT, GPIO_LOW)
#define RXD_INPUT() gpio_direction_input(RXD_PORT)
#define RXD_GET() gpio_get_value(RXD_PORT)
/* spi write a data frame,type mean command or data
3 wire 24 bit SPI interface
*/
static void spi_send_data(unsigned int data)
{
unsigned int i;
CS_SET();
udelay(1);
CLK_SET();
TXD_SET();
CS_CLR();
udelay(1);
for (i = 0; i < 24; i++)
{
//udelay(1);
CLK_CLR();
udelay(1);
if (data & 0x00800000)
{
TXD_SET();
} else
{
TXD_CLR();
}
udelay(1);
CLK_SET();
udelay(1);
data <<= 1;
}
TXD_SET();
CS_SET();
}
static void spi_recv_data(unsigned int *data)
{
unsigned int i = 0, temp = 0x73; //read data
CS_SET();
udelay(1);
CLK_SET();
TXD_SET();
CS_CLR();
udelay(1);
for (i = 0; i < 8; i++) // 8 bits Data
{
udelay(1);
CLK_CLR();
if (temp & 0x80)
TXD_SET();
else
TXD_CLR();
temp <<= 1;
udelay(1);
CLK_SET();
udelay(1);
}
udelay(1);
temp = 0;
for (i = 0; i < 16; i++) // 16 bits Data
{
udelay(1);
CLK_CLR();
udelay(1);
CLK_SET();
udelay(1);
temp <<= 1;
if ((RXD_GET() >> 14) == GPIO_HIGH) //get pin value for mx6sl
{
printk("rxd_get high\n");
temp |= 0x01;
}
}
TXD_SET();
CS_SET();
*data = temp;
}
#define DEVIE_ID (0x70 << 16)
void send_ctrl_cmd(unsigned int cmd)
{
unsigned int out = (DEVIE_ID | cmd);
spi_send_data(out);
}
static void send_data_cmd(unsigned int data)
{
unsigned int out = (DEVIE_ID | (0x2 << 16) | data);
spi_send_data(out);
}
unsigned int ssd2828_read_register(unsigned int reg)
{
unsigned int data = 0;
send_ctrl_cmd(reg);
spi_recv_data(&data);
return (data & 0xffff);
}
void ssd2828_set_register(unsigned int reg_and_value)
{
send_ctrl_cmd(reg_and_value >> 16);
send_data_cmd(reg_and_value & 0x0000ffff);
}
//ed
int ssd2828_probe(struct spi_device *spi)
{
int err;
int sr;
int addrlen;
int i = 0, ret = 0;
unsigned char send[3] = { 0, 0, 0 };
int value = 0;
printk("*************ssd2828 probe *************\n");
ret = gpio_request(SSD2828_RESET_PIN, NULL); //RESET
if (ret != 0)
{
gpio_free(SSD2828_RESET_PIN);
printk("reset pin 39 request fail\n");
return -EIO;
}
gpio_direction_output(SSD2828_RESET_PIN, 1);
ret = gpio_request(CLK_PORT, NULL); //CLK
if (ret != 0)
{
gpio_free(CLK_PORT);
printk("clk pin 108 request fail\n");
return -EIO;
}
gpio_direction_output(CLK_PORT, 1);
ret = gpio_request(TXD_PORT, NULL); //OUTPUT MOSI
if (ret != 0)
{
gpio_free(TXD_PORT);
printk("TXD_PORT 109 request fail\n");
return -EIO;
}
gpio_direction_output(TXD_PORT, 1);
ret = gpio_request(RXD_PORT, NULL); //INPUT MISO
if (ret != 0)
{
gpio_free(RXD_PORT);
printk("rxd pin 110 request fail\n");
return -EIO;
}
gpio_direction_input(RXD_PORT);
ret = gpio_request(CS_PORT, NULL); //CS
if (ret != 0)
{
gpio_free(CS_PORT);
printk("cs pin111 request fail\n");
return -EIO;
}
gpio_direction_output(CS_PORT, 1);
/* reset 2828 */
gpio_direction_output(SSD2828_RESET_PIN, 1);
gpio_set_value(SSD2828_RESET_PIN, GPIO_LOW);
msleep(2000); //sleep 200ms
gpio_set_value(SSD2828_RESET_PIN, GPIO_HIGH);
/* Chip description */
value = ssd2828_read_register(0xb0); //send 0x7000b0
printk("read 0x7000b0 is:0x %0x\n", value);
ret=gpio_get_value(RXD_PORT);
printk("read port is %d\n",ret);
return 0;
}
static int ssd2828_remove(struct spi_device *spi)
{
printk("ssd2828 remove\n");
return 0;
}
/*-------------------------------------------------------------------------*/
static struct spi_driver ssd2828_driver = {
.driver = {
.name = "ssd2828",
.owner = THIS_MODULE,
},
.probe = ssd2828_probe,
.remove = ssd2828_remove,
};
static int __init ssd2828_init(void)
{
int ret = 0;
ssd2828_probe(NULL);
return ret;
}
static void __exit ssd2828_exit(void)
{
printk("ssd2828 exit\n");
gpio_free(39);
gpio_free(108);
gpio_free(109);
gpio_free(110);
gpio_free(111);
}
module_init(ssd2828_init);
module_exit(ssd2828_exit);
MODULE_DESCRIPTION("Driver for ssd2828");
MODULE_AUTHOR("SSL");
MODULE_LICENSE("GPL");