/*
* leds-aw21024.c aw21024 led module
*
* Version: v1.0.0
*
* Copyright (c) 2020 AWINIC Technology CO., LTD
*
* Author: Joseph <jiahuanqing@awinic.com.cn>
*
* 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/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/input.h>
#include <linux/debugfs.h>
#include <linux/miscdevice.h>
#include <linux/syscalls.h>
#include <asm/uaccess.h>
#include <linux/of_gpio.h>
#include <linux/leds.h>
#include <linux/leds-aw21024.h>
#include <linux/leds-aw21024-reg.h>
/******************************************************
*
* Marco
*
******************************************************/
#define AW21024_I2C_NAME "aw21024_led"
#define AW21024_VERSION "v1.0.0"
#define AW_I2C_RETRIES 2
#define AW_I2C_RETRY_DELAY 1
#define AW_READ_CHIPID_RETRIES 2
#define AW_READ_CHIPID_RETRY_DELAY 1
/******************************************************
*
* led effect
*
******************************************************/
#define AW21024_CFG_NAME_MAX 64
AW21024_CFG aw21024_cfg_array[] = {
{aw21024_cfg_led_off, sizeof(aw21024_cfg_led_off)}
,
{aw21024_all_leds_on, sizeof(aw21024_all_leds_on)}
,
{aw21024_red_leds_on, sizeof(aw21024_red_leds_on)}
,
{aw21024_green_leds_on, sizeof(aw21024_green_leds_on)}
,
{aw21024_blue_leds_on, sizeof(aw21024_blue_leds_on)}
,
{aw21024_breath_leds_on, sizeof(aw21024_breath_leds_on)}
};
/******************************************************
*
* aw21024 i2c write/read
*
******************************************************/
static int aw21024_i2c_write(struct aw21024 *aw21024,
unsigned char reg_addr, unsigned char reg_data)
{
int ret = -1;
unsigned char cnt = 0;
while (cnt < AW_I2C_RETRIES) {
ret =
i2c_smbus_write_byte_data(aw21024->i2c, reg_addr, reg_data);
if (ret < 0) {
pr_err("%s: i2c_write cnt=%d error=%d\n", __func__, cnt,
ret);
} else {
break;
}
cnt++;
msleep(AW_I2C_RETRY_DELAY);
}
return ret;
}
static int aw21024_i2c_read(struct aw21024 *aw21024,
unsigned char reg_addr, unsigned char *reg_data)
{
int ret = -1;
unsigned char cnt = 0;
while (cnt < AW_I2C_RETRIES) {
ret = i2c_smbus_read_byte_data(aw21024->i2c, reg_addr);
if (ret < 0) {
pr_err("%s: i2c_read cnt=%d error=%d\n", __func__, cnt,
ret);
} else {
*reg_data = ret;
break;
}
cnt++;
msleep(AW_I2C_RETRY_DELAY);
}
return ret;
}
static int aw21024_i2c_write_bits(struct aw21024 *aw21024,
unsigned char reg_addr, unsigned int mask,
unsigned char reg_data)
{
unsigned char reg_val = 0;
pr_info("%s: enter\n", __func__);
aw21024_i2c_read(aw21024, reg_addr, ®_val);
reg_val &= mask;
reg_val |= reg_data;
aw21024_i2c_write(aw21024, reg_addr, reg_val);
return 0;
}
/*****************************************************
*
* aw21024 led array cfg
*
*****************************************************/
static void aw21024_update_cfg_array(struct aw21024 *aw21024,
unsigned char *p_cfg_data,
unsigned int cfg_size)
{
unsigned int i = 0;
pr_info("%s: enter\n", __func__);
for (i = 0; i < cfg_size; i += 2)
aw21024_i2c_write(aw21024, p_cfg_data[i], p_cfg_data[i + 1]);
}
static int aw21024_cfg_update_array(struct aw21024 *aw21024)
{
pr_info("%s: enter\n", __func__);
aw21024_update_cfg_array(aw21024, aw21024_cfg_array[aw21024->effect].p,
aw21024_cfg_array[aw21024->effect].count);
return 0;
}
static int aw21024_hw_reset(struct aw21024 *aw21024)
{
pr_info("%s: enter\n", __func__);
if (aw21024 && gpio_is_valid(aw21024->reset_gpio)) {
gpio_set_value_cansleep(aw21024->reset_gpio, 0);
msleep(1);
gpio_set_value_cansleep(aw21024->reset_gpio, 1);
usleep_range(2000, 2500);
} else {
dev_err(aw21024->dev, "%s: failed\n", __func__);
}
pr_info("%s: enter out\n", __func__);
return 0;
}
static int aw21024_hw_off(struct aw21024 *aw21024)
{
pr_info("%s: enter\n", __func__);
if (aw21024 && gpio_is_valid(aw21024->reset_gpio)) {
gpio_set_value_cansleep(aw21024->reset_gpio, 0);
msleep(1);
} else {
dev_err(aw21024->dev, "%s: failed\n", __func__);
}
return 0;
}
/*****************************************************
*
* aw21024 led function
*
*****************************************************/
static int aw21024_chip_enable(struct aw21024 *aw21024, bool flag)
{
pr_info("%s: enter\n", __func__);
if (flag) {
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CHIP_EN_CLOSE_MASK,
AW21024_BIT_CHIP_EN);
} else {
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CHIP_EN_CLOSE_MASK,
AW21024_BIT_CHIP_CLOSE);
}
return 0;
}
static int aw21024_clkfrq_set(struct aw21024 *aw21024, unsigned int mode)
{
pr_info("%s: enter\n", __func__);
switch (mode) {
case AW21024_CLKPRQ_16MH:
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CLKPRQ_MASK,
AW21024_BIT_CLKPRQ_16MH);
break;
case AW21024_CLKPRQ_8MH:
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CLKPRQ_MASK,
AW21024_BIT_CLKPRQ_8MH);
break;
case AW21024_CLKPRQ_1MH:
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CLKPRQ_MASK,
AW21024_BIT_CLKPRQ_1MH);
break;
case AW21024_CLKPRQ_512KH:
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CLKPRQ_MASK,
AW21024_BIT_CLKPRQ_512KH);
break;
case AW21024_CLKPRQ_256KH:
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CLKPRQ_MASK,
AW21024_BIT_CLKPRQ_256KH);
break;
case AW21024_CLKPRQ_125KH:
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CLKPRQ_MASK,
AW21024_BIT_CLKPRQ_125KH);
break;
case AW21024_CLKPRQ_62KH:
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CLKPRQ_MASK,
AW21024_BIT_CLKPRQ_62KH);
break;
case AW21024_CLKPRQ_31KH:
aw21024_i2c_write_bits(aw21024,
AW21024_REG_GCR,
AW21024_BIT_CLKPRQ_MASK,
AW21024_BIT_CLKPRQ_31KH);
break;
default:
break;
}
return 0;
}
static int aw21024_br_update(struct aw21024 *aw21024)
{
aw21024_i2c_write(aw21024, AW21024_REG_UPDATE, 0x00);
return 0;
}
static int aw21024_sw_reset(struct aw21024 *aw21024)
{
aw21024_i2c_write(aw21024, AW21024_REG_RESET, 0x00);
return 0;
}
/*****************************************************
*
* aw21024 led brightness
*
*****************************************************/
static void aw21024_brightness_work(struct work_struct *work)
{
struct aw21024 *aw21024 = container_of(work, struct aw21024,
brightness_work);
pr_info("%s: enter\n", __func__);
if (aw21024->cdev.brightness > aw21024->cdev.max_brightness)
aw21024->cdev.brightness = aw21024->cdev.max_brightness;
aw21024_i2c_write(aw21024, AW21024_REG_GCCR, aw21024->cdev.brightness);
}
static void aw21024_set_brightness(struct led_classdev *cdev,
enum led_brightness brightness)
{
struct aw21024 *aw21024 = container_of(cdev, struct aw21024, cdev);
aw21024->cdev.brightness = brightness;
schedule_work(&aw21024->brightness_work);
}
/*****************************************************
*
* check chip id
*
*****************************************************/
static int aw21024_read_chipid(struct aw21024 *aw21024)
{
int ret = -1;
unsigned char cnt = 0;
unsigned char reg_val = 0;
pr_info("%s: enter\n", __func__);
while (cnt < AW_READ_CHIPID_RETRIES) {
ret = aw21024_i2c_read(aw2
aw21024驱动与资料.rar
5星 · 超过95%的资源 需积分: 5 81 浏览量
2021-04-27
16:48:14
上传
评论
收藏 2.08MB RAR 举报
东皇※太一
- 粉丝: 1099
- 资源: 32
最新资源
- IMG_20240425_120538.jpg
- My Complete Genome_6k Base-Pairs of Phenotype SNPs_Complete Raw Data.zip
- qt 的mqtt测试demo
- 移动应用开发教程-zip.zip
- mosquitto-2.018-install-windows-x64
- FTPServer FTP 服务器,绿色免安装,单文件
- 梦畅语音点名软件,上课点名
- 利用ADNI数据集和标签,在tensorflow框架上使用tensorlayer接口,通过架构u-net实现海马体的分割
- Kutools for Word v9.0 office word 插件
- 修复Windows 10 LTSC 2021资源占用率高
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论5