80,363
社区成员
发帖
与我相关
我的任务
分享
static int alarm_set_rtc(struct timespec *ts)
{
struct rtc_time new_rtc_tm;
struct rtc_device *rtc_dev;
unsigned long flags;
int rv = 0;
rtc_time_to_tm(ts->tv_sec, &new_rtc_tm);
rtc_dev = alarmtimer_get_rtcdev(); //rtc注册到i2c device中时,这里就找获取不到rtc_dev
rv = do_settimeofday(ts);
if (rv < 0)
return rv;
if (rtc_dev)
{
printk("#### [kernel] %s %s %d ####\n", __FILE__, __FUNCTION__, __LINE__);
rv = rtc_set_time(rtc_dev, &new_rtc_tm);
}
spin_lock_irqsave(&alarm_slock, flags);
alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
wake_up(&alarm_wait_queue);
spin_unlock_irqrestore(&alarm_slock, flags);
return rv;
}
/*
* An rtc/i2c driver for the EM Microelectronic EM3027
* Copyright 2011 CompuLab, Ltd.
*
* Author: Mike Rapoport <mike@compulab.co.il>
*
* Based on rtc-ds1672.c by Alessandro Zummo <a.zummo@towertech.it>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/module.h>
/* Registers */
#define EM3027_REG_ON_OFF_CTRL 0x00
#define EM3027_REG_IRQ_CTRL 0x01
#define EM3027_REG_IRQ_FLAGS 0x02
#define EM3027_REG_STATUS 0x03
#define EM3027_REG_RST_CTRL 0x04
#define EM3027_REG_WATCH_SEC 0x08
#define EM3027_REG_WATCH_MIN 0x09
#define EM3027_REG_WATCH_HOUR 0x0a
#define EM3027_REG_WATCH_DATE 0x0b
#define EM3027_REG_WATCH_DAY 0x0c
#define EM3027_REG_WATCH_MON 0x0d
#define EM3027_REG_WATCH_YEAR 0x0e
#define EM3027_REG_ALARM_SEC 0x10
#define EM3027_REG_ALARM_MIN 0x11
#define EM3027_REG_ALARM_HOUR 0x12
#define EM3027_REG_ALARM_DATE 0x13
#define EM3027_REG_ALARM_DAY 0x14
#define EM3027_REG_ALARM_MON 0x15
#define EM3027_REG_ALARM_YEAR 0x16
static struct i2c_driver em3027_driver;
static int em3027_get_time(struct device *dev, struct rtc_time *tm)
{
return 0;
}
static int em3027_set_time(struct device *dev, struct rtc_time *tm)
{
return 0;
}
static const struct rtc_class_ops em3027_rtc_ops = {
.read_time = em3027_get_time,
.set_time = em3027_set_time,
};
//em3027_probe中, rtc注册到&client->dev时,android系统里面设置时间时找不到rtc设备。
static int em3027_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct rtc_device *rtc;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
rtc = devm_rtc_device_register(&client->dev, em3027_driver.driver.name, &em3027_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
i2c_set_clientdata(client, rtc);
return 0;
}
static int em3027_remove(struct i2c_client *client)
{
return 0;
}
static struct i2c_device_id em3027_id[] = {
{ "i2c-rtc", 0 },
{ }
};
static struct i2c_driver em3027_driver = {
.driver = {
.name = "aml-rtc-em3027",
},
.probe = &em3027_probe,
.remove = &em3027_remove,
.id_table = em3027_id,
};
module_i2c_driver(em3027_driver);
MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver");
MODULE_LICENSE("GPL");
/*
* this driver is written for the internal rtc for M1
*/
#include<linux/module.h>
#include<linux/platform_device.h>
#include<linux/rtc.h>
#include<linux/slab.h>
#include<asm/delay.h>
#include<mach/am_regs.h>
#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6
#include <plat/io.h>
#endif
#include <linux/of.h>
struct aml_rtc_priv{
struct rtc_device *rtc;
unsigned long base_addr;
struct timer_list timer;
struct work_struct work;
struct workqueue_struct *rtc_work_queue;
};
typedef struct alarm_data_s {
int level;
unsigned alarm_sec; //in s
} alarm_data_t;
//这里的to_i2c_client找不到dev
static int aml_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
return pt7c4337_get_datetime(to_i2c_client(dev), tm);
}
static int aml_rtc_write_time(struct device *dev, struct rtc_time *tm)
{
return pt7c4337_set_datetime(to_i2c_client(dev), tm);
}
static const struct rtc_class_ops aml_rtc_ops ={
.read_time = aml_rtc_read_time,
.set_time = aml_rtc_write_time,
.set_alarm = aml_rtc_set_alarm,
};
static int aml_rtc_probe(struct platform_device *pdev)
{
struct aml_rtc_priv *priv;
struct device_node* aml_rtc_node = pdev->dev.of_node;
int ret;
int sec_adjust = 0;
priv = (struct aml_rtc_priv *)kzalloc(sizeof(*priv), GFP_KERNEL);
if(!priv)
return -ENOMEM;
platform_set_drvdata(pdev, priv);
/* platform setup code should have handled this; sigh */
if (!device_can_wakeup(&pdev->dev))
device_init_wakeup(&pdev->dev, 1);
priv->rtc = rtc_device_register("aml_rtc", &pdev->dev, &aml_rtc_ops, THIS_MODULE);
if(IS_ERR(priv->rtc)){
ret = PTR_ERR(priv->rtc);
goto out;
}
return 0;
out:
if(priv->rtc_work_queue)
destroy_workqueue(priv->rtc_work_queue);
kfree(priv);
return ret;
}
static const struct of_device_id meson6_rtc_dt_match[]={
{ .compatible = "amlogic,aml_rtc"},
{},
};
struct platform_driver aml_rtc_driver = {
.driver = {
.name = "aml_rtc",
.owner = THIS_MODULE,
.of_match_table=meson6_rtc_dt_match,
},
.probe = aml_rtc_probe,
};
static int __init aml_rtc_init(void)
{
return platform_driver_register(&aml_rtc_driver);
}
static void __init aml_rtc_exit(void)
{
return platform_driver_unregister(&aml_rtc_driver);
}
module_init(aml_rtc_init);
module_exit(aml_rtc_exit);
MODULE_DESCRIPTION("Amlogic internal rtc driver");
MODULE_LICENSE("GPL");