RK3188&AW9523B I2C接口LED驱动(2)

之前做了一个GPIO模式下的LED驱动,由于是按I2C总线分组设置LED的,所以在实际应用中是不够的,这次根据文档完成了LED模式下的LED驱动,及单个灯可控驱动。
根据文档可知,配置13H寄存器为0即可设P1_7-P1_0为LED模式。
LED模式切换寄存器
而LED模式下的控制相对GPIO模式要简单的多,只需要对每个口连接的灯设置颜色即可,这里的颜色是如下图对应的颜色,分为256个级别,及红黄蓝各有256个级别;
这里写图片描述
例如P1_0口接的是红灯,而P1_1接的是绿,P1_2接的是蓝,则如需要显示红色则对节点传入ff0000即可。
代码如下:

static void switch_to_led_mode()
{
    //配置成LED模式
    char buffer[LED_REG_LEN];
    int ret = 0;
    printk("in:%s, line:%d\n", __func__, __LINE__);
    buffer[0] = 0x12; //AW9523B register P0 address
    buffer[1] = 0x00; //0x1101 1011
    ret = led_tx8_data(this_client, &buffer[0], 2);
    ret = led_rx_data(this_client, &buffer[0], 1);
    buffer[0] = 0x13; //AW9523B register P1 address
    buffer[1] = 0x00; //0x1110 0110
    ret = led_tx8_data(this_client, &buffer[0], 2);
    ret = led_rx_data(this_client, &buffer[0], 1);
    printk("in:%s, line:%d\n", __func__, __LINE__);
}

由于之前代码太凌乱,所以由带头大哥帮忙整理了下代码,瞬间把我秒成渣了。
SYS节点注册:

#define CREATE_SYSFS_LED(obj,_name,_port) \
{\
    ret = sysfs_create_file(obj, &dev_attr_##_name##_port.attr);\
    if (ret) {\
        printk(KERN_ERR "i2c0_led_sysfs_init:" "sysfs_create_group failed\n");\
        goto err4;\
    }\
}

static int i2c0_led_sysfs_init(void)
{
    int ret ;

    led_kobj = kobject_create_and_add("android_i2c0_led", NULL);
    if (led_kobj == NULL) {
        printk(KERN_ERR
                    "i2c0_led_sysfs_init:"\
                    "subsystem_register failed\n");
        ret = -ENOMEM;
        goto err;
    }

    CREATE_SYSFS_LED(led_kobj, led, 2);     
    CREATE_SYSFS_LED(led_kobj, led, 3);     
    CREATE_SYSFS_LED(led_kobj, led, 4);     
    CREATE_SYSFS_LED(led_kobj, led, 5); 
    CREATE_SYSFS_LED(led_kobj, led, 6);

    printk("i2c_led0_sysfs_init ++++++++++++++++\n");
    return 0 ;
err4:
    kobject_del(led_kobj);
err:
    return ret ;
}

DEVICE_ATTR show和store函数:

//将传入的要显示的颜色值分别出红绿蓝对应的值
static void int_convert_to_color_t(int value,unsigned char *red,unsigned char *green,unsigned char * blue)
{
     *blue=value&0xFF;
     value=value/256;
     *green=value&0xFF;
     value=value/256;
     *red=value&0xFF;

}
static ssize_t  led_store(struct device *dev,
            struct device_attribute *attr,const char *buf, size_t count,int port)
{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
    int color;

    if(port> LED_MAX)
         return -1;

    printk("set led =%d color=%s \n",port,buf);
    #if 1
    sscanf(buf, "%du", &color);
    int_convert_to_color_t(color,&red,&green,&blue);
    all_led[port].color.red=red;
    all_led[port].color.green=green;
    all_led[port].color.blue=blue;
    set_led_color(all_led[port]);
    printk("ok red=%d green=%d blue=%d \n",red,green,blue);
    #endif

    return count;
}

static ssize_t led_show(struct device *dev,
            struct device_attribute *attr, char *buf,int port)
{
    int red_value = 0, green_value = 0, blue_value = 0;
    ssize_t ret = 0;

    printk("cat debug buf++++++++++++++++++++++++++++++++++++=\n");
    red_value = all_led[port].color.red;
    green_value = all_led[port].color.green;
    blue_value = all_led[port].color.blue;
    ret = red_value * 256 * 256 + green_value * 256 + blue_value;
    printk("++++++ret = %d\n++++++", ret);

    sprintf(buf, "ret = %d\n", ret);
    ret = strlen(buf) + 1;
    return ret;
}

#define  LED_DEVICE_ATTR(name_,_port) \
static ssize_t led_show_##_port(struct device *dev, \
                struct device_attribute *attr, char *buf) \
{\
   return  led_show(dev,attr,buf,_port);\    
}\
static ssize_t led_store_##_port(struct device *dev,\
                struct device_attribute *attr,const char *buf, size_t count)\
{\
   return led_store(dev,attr,buf,count,_port);\
}\
static DEVICE_ATTR(name_##_port, 0666,led_show_##_port, led_store_##_port);

LED_DEVICE_ATTR(led, 2)
LED_DEVICE_ATTR(led, 3)
LED_DEVICE_ATTR(led, 4)
LED_DEVICE_ATTR(led, 5)
LED_DEVICE_ATTR(led, 6)

设置灯口以及灯口对应的颜色值:

typedef struct{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
}rgb_reg_t;

typedef struct{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
}color_t;

typedef struct{
    rgb_reg_t reg;
    color_t color;
}led_t;

static void set_led_RGB(unsigned char reg,unsigned char data)
{
    char buffer[LED_REG_LEN];
    buffer[0]=reg;
    buffer[1]=data;
    //buffer[0]是寄存器地址,buffer[1]是传入的数据
    led_tx8_data(this_client, &buffer[0], 2);
    led_rx_data(this_client, &buffer[0], 1);
}



static void set_led_color(led_t led)
{
    set_led_RGB(led.reg.red,led.color.red);
    set_led_RGB(led.reg.green,led.color.green);
    set_led_RGB(led.reg.blue,led.color.blue);
}

static void init_all_led()
{
     //led 6
     all_led[LED_6].reg.red = GPIO_P1_4;
     all_led[LED_6].reg.green = GPIO_P1_5;
     all_led[LED_6].reg.blue = GPIO_P1_6;

     //led 5     
     all_led[LED_5].reg.red = GPIO_P0_5;
     all_led[LED_5].reg.green = GPIO_P0_6;
     all_led[LED_5].reg.blue = GPIO_P0_7;

     //led 4
     all_led[LED_4].reg.red = GPIO_P0_2;
     all_led[LED_4].reg.green = GPIO_P0_3;
     all_led[LED_4].reg.blue = GPIO_P0_4;

     //led 3     
     all_led[LED_3].reg.red = GPIO_P1_3;
     all_led[LED_3].reg.green = GPIO_P0_0;
     all_led[LED_3].reg.blue = GPIO_P0_1;

     //led 2
     all_led[LED_2].reg.red = GPIO_P1_0;
     all_led[LED_2].reg.green = GPIO_P1_1;
     all_led[LED_2].reg.blue = GPIO_P1_2;
}

于是乎,原本杂乱不堪的代码,瞬间就高大上了啊,哈哈~

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值