日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

BL5372 RTC linux驱动

發布時間:2023/12/8 linux 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BL5372 RTC linux驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 硬件
    BL5372 RTC
    https://www.belling.com.cn/product_info.html?id=65
  • 驅動
  • /** An I2C driver for Beilin BL5372 RTC*/#include <linux/i2c.h> #include <linux/bcd.h> #include <linux/rtc.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/of.h>#define DEG 0#define DRV_VERSION "0.0.1"#define TIME24 1 #define RS5C_ADDR(R) (((R) << 4) | 0) #define RS5C372_REG_SECS 0 #define RS5C372_REG_MINS 1 #define RS5C372_REG_HOURS 2 #define RS5C372_REG_WDAY 3 #define RS5C372_REG_DAY 4 #define RS5C372_REG_MONTH 5 #define RS5C372_REG_YEAR 6 #define RS5C372_REG_TRIM 7 #define RS5C_REG_ALARM_A_MIN 8 /* or ALARM_W */ #define RS5C_REG_ALARM_A_HOURS 9 #define RS5C_REG_ALARM_A_WDAY 10#define RS5C_REG_ALARM_B_MIN 11 /* or ALARM_D */ #define RS5C_REG_ALARM_B_HOURS 12 #define RS5C_REG_ALARM_B_WDAY 13 /* (ALARM_B only) */ #define RS5C_REG_CTRL1 14 #define RS5C_REG_CTRL2 15 #define DEVICE_ADDR 0x32 //0x5d#if 0 //11 ---> 0x11 static unsigned char bin2bcd(unsigned val) {return ((val / 10) << 4) + val % 10; } //0x11---> 11 static unsigned bcd2bin(unsigned char val) {return (val & 0x0f) + (val >> 4) * 10; } #endifstatic unsigned rs5c_reg2hr(unsigned reg) { #if TIME24return bcd2bin(reg & 0x3f); #elseunsigned hour;hour = bcd2bin(reg & 0x1f);if (hour == 12)hour = 0;if (reg & 0x20)hour += 12;return hour; #endif }static unsigned rs5c_hr2reg(unsigned hour) {#if TIME24return bin2bcd(hour);#elseif (hour > 12)return 0x20 | bin2bcd(hour - 12);if (hour == 12)return 0x20 | bin2bcd(12);if (hour == 0)return bin2bcd(12);return bin2bcd(hour); #endif }//----------------------------------------------- static struct i2c_driver bl5372_driver;struct bl5372 {struct rtc_device *rtc;struct device *dev;int irq;/*unsigned char sec;unsigned char min;unsigned char hour;unsigned char week;unsigned char day;unsigned char month;unsigned int year;*/ };static int i2c_write_bytes(struct i2c_client *client, uint8_t *data, uint16_t len) {struct i2c_msg msg;int ret=-1;msg.flags = !I2C_M_RD;msg.addr = client->addr;msg.len = len;msg.buf = data;ret=i2c_transfer(client->adapter, &msg,1);return ret; }static int bl5372_get_datetime(struct i2c_client *client, struct rtc_time *tm) {struct bl5372 *bl5372 = i2c_get_clientdata(client);unsigned char buf[7] = { RS5C_ADDR(RS5C372_REG_SECS) };struct i2c_msg msgs[] = {{/* setup read ptr */.addr = client->addr,.flags = 0,/* write */.len = 1,.buf = buf},{/* read the sec,min,hour,week,day,month,year */.addr = client->addr,.flags = I2C_M_RD,/* read */.len = 7,.buf = buf},};//int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)//@num: Number of messages to be executed.//這里有兩個消息, msgs[]的大小/* read registers */if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {dev_err(&client->dev, "%s: read error\n", __func__);return -EIO;}tm->tm_sec = bcd2bin(buf[0] & 0x7f);tm->tm_min = bcd2bin(buf[1] & 0x7f);tm->tm_hour = rs5c_reg2hr(buf[2]);tm->tm_mday = bcd2bin(buf[4] & 0x7f);;tm->tm_wday = bcd2bin(buf[3] & 0x7f);tm->tm_mon = rs5c_reg2hr(buf[5])-1;tm->tm_year = bcd2bin(buf[6] & 0x7f)+100;//------------------------------------buf[0]= RS5C_ADDR(RS5C_REG_CTRL2);struct i2c_msg msgs2[] = {{/* setup read */.addr = client->addr,.len = 1,.buf = buf},{/* read is_24hour */.addr = client->addr,.flags = I2C_M_RD,.len = 1,.buf = buf},};/* read registers */if ((i2c_transfer(client->adapter, msgs2, 2)) != 2) {dev_err(&client->dev, "%s: read error\n", __func__);return -EIO;}if(buf[0]&0x20){tm->tm_hour= (tm->tm_hour<24)? (tm->tm_hour):(24-tm->tm_hour);}else{tm->tm_hour=(tm->tm_hour<24-8)? (tm->tm_hour+8):(tm->tm_hour+8-24);}/* the clock can give out invalid datetime, but we cannot return* -EINVAL otherwise hwclock will refuse to set the time on bootup.*/if (rtc_valid_tm(tm) < 0)dev_err(&client->dev, "retrieved date/time is not valid.\n");return 0; }static int bl5372_set_datetime(struct i2c_client *client, struct rtc_time *tm) {struct bl5372 *bl5372 = i2c_get_clientdata(client);int i, err;unsigned char buf[7];//------------------------------------buf[0]= RS5C_ADDR(RS5C_REG_CTRL2);struct i2c_msg msgs2[] = {{/* setup read */.addr = client->addr,.len = 1,.buf = buf},{/* read is_24hour */.addr = client->addr,.flags = I2C_M_RD,.len = 1,.buf = buf},};/* read registers */if ((i2c_transfer(client->adapter, msgs2, 2)) != 2) {dev_err(&client->dev, "%s: read error\n", __func__);return -EIO;}if((buf[0]&0x20)== 0){buf[0] |= (1<<5); err = i2c_master_send(client, buf, 1);} //------------------------/* hours, minutes and seconds */buf[0] = bin2bcd(tm->tm_sec);buf[1] = bin2bcd(tm->tm_min);buf[2] = rs5c_hr2reg(tm->tm_hour);buf[3] = bin2bcd(tm->tm_wday & 0x07); //week 0~6buf[4] = bin2bcd(tm->tm_mday);buf[5] = bin2bcd(tm->tm_mon)+1;// 0~11tm->tm_year -= 100;buf[6] = bin2bcd(tm->tm_year % 100);// start at 1900 2018=>118err = i2c_smbus_write_byte_data(client, RS5C_ADDR(RS5C372_REG_SECS), buf[0]);i2c_smbus_write_byte_data(client, RS5C_ADDR(RS5C372_REG_MINS) , buf[1]);i2c_smbus_write_byte_data(client, RS5C_ADDR(RS5C372_REG_HOURS) , buf[2]);i2c_smbus_write_byte_data(client, RS5C_ADDR(RS5C372_REG_WDAY) , buf[3]);i2c_smbus_write_byte_data(client, RS5C_ADDR(RS5C372_REG_DAY) , buf[4]);i2c_smbus_write_byte_data(client, RS5C_ADDR(RS5C372_REG_MONTH) , buf[5]);i2c_smbus_write_byte_data(client, RS5C_ADDR(RS5C372_REG_YEAR) , buf[6]);return 0; }#ifdef CONFIG_RTC_INTF_DEV static int bl5372_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) {struct bl5372 *bl5372 = i2c_get_clientdata(to_i2c_client(dev));struct rtc_time tm;switch (cmd) {case RTC_RD_TIME://bl5372_get_datetime(to_i2c_client(dev), &tm);return 0;case RTC_SET_TIME:if (copy_from_user(&tm, arg, sizeof(tm)))return -EFAULT;bl5372_set_datetime(to_i2c_client(dev), &tm);return 0;default:return -ENOIOCTLCMD;}} #else #define bl5372_rtc_ioctl NULL #endifstatic int bl5372_rtc_read_time(struct device *dev, struct rtc_time *tm) {return bl5372_get_datetime(to_i2c_client(dev), tm); }static int bl5372_rtc_set_time(struct device *dev, struct rtc_time *tm) {return bl5372_set_datetime(to_i2c_client(dev), tm); }static int bl5372_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm) {struct bl5372 *bl5372 = i2c_get_clientdata(to_i2c_client(dev));return 0; }static int bl5372_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) {struct bl5372 *bl5372 = i2c_get_clientdata(to_i2c_client(dev));return 0; }static int bl5372_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) {//struct bl5372 *bl5372 = dev_get_drvdata(dev);struct bl5372 *bl5372 = i2c_get_clientdata(to_i2c_client(dev));return 0; }static const struct rtc_class_ops bl5372_rtc_ops = {.ioctl = bl5372_rtc_ioctl,.read_time = bl5372_rtc_read_time,.set_time = bl5372_rtc_set_time,.read_alarm = bl5372_rtc_getalarm,.set_alarm = bl5372_rtc_setalarm,.alarm_irq_enable = bl5372_rtc_alarm_irq_enable };static int bl5372_probe(struct i2c_client *client,const struct i2c_device_id *id) {struct bl5372 *bl5372;if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){return -ENODEV;}bl5372 = devm_kzalloc(&client->dev, sizeof(struct bl5372),GFP_KERNEL);if (!bl5372){return -ENOMEM;}device_init_wakeup(&client->dev, 1);i2c_set_clientdata(client, bl5372);bl5372->rtc = devm_rtc_device_register(&client->dev,bl5372_driver.driver.name,&bl5372_rtc_ops, THIS_MODULE);if (IS_ERR(bl5372->rtc)){return PTR_ERR(bl5372->rtc);}return 0; }static int bl5372_remove(struct i2c_client *client) {return 0; }static const struct i2c_device_id bl5372_id[] = {{ "bl5372", 0 },{ } }; MODULE_DEVICE_TABLE(i2c, bl5372_id);#ifdef CONFIG_OF static const struct of_device_id bl5372_of_match[] = {{ .compatible = "beilin,bl5372" },{} }; MODULE_DEVICE_TABLE(of, bl5372_of_match); #endifstatic struct i2c_driver bl5372_driver = {.driver = {.name = "rtc-bl5372",.owner = THIS_MODULE,.of_match_table = of_match_ptr(bl5372_of_match),},.probe = bl5372_probe,.remove = bl5372_remove,.id_table = bl5372_id, };module_i2c_driver(bl5372_driver);MODULE_AUTHOR("Zhengweiqing <1548889230@qq.com>"); MODULE_DESCRIPTION("Beilin BL5372 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION);

    總結

    以上是生活随笔為你收集整理的BL5372 RTC linux驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产精品羞羞答答在线 | 69视频在线免费观看 | 伊人自拍 | 国产福利视频网站 | 欧美一级黄色片网站 | 丰满岳妇伦在线播放 | 国产成人小视频 | 亚洲免费色视频 | 丁香花电影免费播放在线观看 | 欧美不卡一二三 | 国产精品2018 | 在线观看欧美一区 | 欧美日韩中文字幕在线播放 | 久久精品无码一区二区三区毛片 | 久草一区 | 91福利专区 | 超碰一区二区三区 | 激情免费网站 | 在线观看自拍 | 欧美在线黄 | 色哟哟国产精品 | 另类欧美日韩 | 91国产精品一区 | 香蕉视频免费在线播放 | 日韩黄色一级大片 | 亚洲熟女综合色一区二区三区 | 亚洲国产精品女人 | 两性午夜免费视频 | av青青| 欧美在线精品一区二区三区 | 欧美性色a| 国产主播精品在线 | 亚洲一区二区三区婷婷 | 伊人色网| 亚洲第一网站 | 99色亚洲 | 成人av中文字幕 | 无码精品一区二区三区在线播放 | 国产不卡在线观看视频 | 久久aaa | 国产三级在线观看完整版 | 天天狠天天插天天透 | 日本理论片午伦夜理片在线观看 | 青青青青青草 | 色女人网站 | 亚洲欧美国产一区二区三区 | 黄色一级视频免费看 | 久久这里只有 | 成人在线免费高清视频 | 精品无码人妻一区二区三区 | 福利在线免费观看 | 校园春色av | 免费看黄20分钟 | 亚洲成年人网站在线观看 | 亚洲人在线观看 | 官场艳妇疯狂性关系 | 日韩一区二区三区视频 | 国产人妻aⅴ色偷 | 欧美成人免费观看 | 免费看黄色漫画 | 日日摸天天爽天天爽视频 | 久久露脸 | 91传媒理伦片在线观看 | www黄色av | 色福利网 | 一本色道久久综合亚洲二区三区 | 天堂a√在线 | 国产精品亚洲一区 | 熟妇五十路六十路息与子 | 久久精品视频网 | 中文毛片无遮挡高潮免费 | 男女激情大尺度做爰视频 | 18禁男女爽爽爽午夜网站免费 | 96视频在线| 国产熟女一区二区 | 黄色成人av网站 | 国产精品久久久久久人妻精品动漫 | av最新地址 | 美女又大又黄 | 亚洲av综合色区无码二区爱av | 天海翼av在线 | 97久久人人超碰caoprom欧美 | 波多野结衣在线视频播放 | 国产视频h | 精品国自产在线观看 | 亚洲爽爽爽 | 成人污污视频 | 国产农村熟妇videos | 日韩一二区 | 青青偷拍视频 | 97超碰人人看 | 91精品视频免费 | 免费看黄色三级三级 | 久久久久人妻精品一区二区三区 | av在线免播放器 | www.久久视频| 国产精品videossex久久发布 | 麻豆一区产品精品蜜桃的特点 | 久久国产精品影院 |