在博客http://blog.csdn.net/weixin_40109283/article/details/79399304中给出了基于DragonBoard 410c的彩灯设计的硬件介绍,驱动代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define nws 16
unsigned long blue = 0x00ff00;
unsigned long red = 0xff0000;
unsigned long green = 0x0000ff;
unsigned long white = 0xffffff;
unsigned long orange= 0xff7f00;
unsigned long indigo= 0xff00ff;
unsigned long purple= 0x00ffff;
unsigned long black = 0x000000;
struct ws2801_data {
struct platform_device *pdev;
int ws2801_ck;
int ws2801_si;
};
static struct ws2801_data* data;
static void send0(void)
{
gpio_set_value(data->ws2801_si, 0);
gpio_set_value(data->ws2801_ck, 0);
ndelay(500);
gpio_set_value(data->ws2801_ck, 1);
ndelay(500);
}
static void send1(void)
{
gpio_set_value(data->ws2801_si, 1);
gpio_set_value(data->ws2801_ck, 0);
ndelay(500);
gpio_set_value(data->ws2801_ck, 1);
ndelay(500);
}
static void ws_reset(void)
{
gpio_set_value(data->ws2801_ck, 0);
udelay(500);
}
static void sendbyte(unsigned long dat)
{
unsigned char i;
for (i = 0; i < 24; i++) {
if (0x800000 == (dat & 0x800000))
send1();
else
send0();
dat <<= 1;
}
}
static void sendws(unsigned long wsdata)
{
unsigned char j;
for (j = 0; j < nws; j++)
sendbyte(wsdata);
ws_reset();
}
static void ws2801_init(void)
{
sendws(red);
ssleep(1);
sendws(green);
}
static void sendrgb(void)
{
unsigned char i;
for (i = 0; i < 5; i++) {
sendbyte(red);
sendbyte(green);
sendbyte(blue);
}
ws_reset();
}
static void sendbrg(void)
{
unsigned char i;
for (i = 0; i < 5; i++) {
sendbyte(blue);
sendbyte(red);
sendbyte(green);
}
ws_reset();
}
static void sendgbr(void)
{
unsigned char i;
for (i = 0; i < 5; i++) {
sendbyte(green);
sendbyte(blue);
sendbyte(red);
}
ws_reset();
}
static ssize_t ws2801_store_value(struct device *dev, struct device_attribute* attr,
const char *buf, size_t len)
{
int ret;
unsigned long v;
ret = kstrtoul(buf, 10, &v);
switch (v) {
case 0:
sendws(black);
break;
case 1:
sendws(red);
break;
case 2:
sendws(green);
break;
case 3:
sendws(blue);
break;
case 4:
sendws(white);
break;
case 5:
sendws(orange);
break;
case 6:
sendws(purple);
break;
case 7:
sendws(indigo);
break;
case 8:
sendrgb();
break;
case 9:
sendbrg();
break;
case 10:
sendgbr();
break;
default:
return -EINVAL;
}
return len;
}
static DEVICE_ATTR(value, 0664, NULL, ws2801_store_value);
static int ws2801_probe(struct platform_device *pdev)
{
int result;
struct device_node* node = pdev->dev.of_node;
printk("ws2801 probe entern");
data = devm_kzalloc(&pdev->dev, sizeof(struct ws2801_data), GFP_KERNEL);
if (!data) {
pr_err("%s kzalloc errorn", __FUNCTION__);
return -ENOMEM;
}
dev_set_drvdata(&pdev->dev, data);
data->ws2801_ck = of_get_named_gpio(node, "thundersoft,ws2801_ck", 0);
if (!gpio_is_valid(data->ws2801_ck)) {
pr_err("ws2801 ck not specifiedn");
goto err1;
} else {
result = gpio_request(data->ws2801_ck, "ws2801_ck");
if (result < 0) {
pr_err("Unable to request ws2801 ckn");
goto err1;
} else {
gpio_direction_output(data->ws2801_ck, 0);
}
}
data->ws2801_si = of_get_named_gpio(node, "thundersoft,ws2801_si", 0);
if (!gpio_is_valid(data->ws2801_si)) {
pr_err("ws2801 si not specifiedn");
goto err2;
} else {
result = gpio_request(data->ws2801_si, "ws2801_si");
if (result < 0) {
pr_err("Unable to request ws2801 sin");
goto err2;
} else {
gpio_direction_output(data->ws2801_si, 0);
}
}
result = sysfs_create_file(&pdev->dev.kobj, &dev_attr_value.attr);
if (result < 0) {
printk("sysfs create file failedn");
goto err3;
}
ws2801_init();
printk(KERN_INFO "ws2801 probe successn");
return 0;
err3:
gpio_free(data->ws2801_si);
err2:
gpio_free(data->ws2801_ck);
err1:
kfree(data);
printk(KERN_ERR "ws2801 probe failedn");
return -EINVAL;
}
static int ws2801_remove(struct platform_device *pdev)
{
gpio_free(data->ws2801_si);
gpio_free(data->ws2801_ck);
kfree(data);
return 0;
}
static struct of_device_id ws2801_match_table[] = {
{ .compatible = "thundersoft,ws2801"},
{ },
};
static struct platform_driver ws2801_driver = {
.probe = ws2801_probe,
.remove = ws2801_remove,
.driver = {
.owner = THIS_MODULE,
.name = "ws2801",
.of_match_table = ws2801_match_table,
},
};
module_platform_driver(ws2801_driver);
MODULE_AUTHOR("heql0703@thundersoft.com");
MODULE_LICENSE("GPL");
|