Registrieren  •  Login 
  
 
im Forum


 News   Pastebin   Online-Tools   Kontakt 


Pastebin
Dieser Code wurde am 05.05.2013, 19:45 von killerbees19 hochgeladen und 1 mal geändert.

Direktlink zu diesem Code: https://www.happytec.at/pastebin/view.php?id=256

Diff
  1. From fd5ff2d88f470ed70ff58393eee61110b181816a Mon Sep 17 00:00:00 2001
  2. From: Andy Duller <andyd@afterthoughtsoftware.com>
  3. Date: Thu, 8 Nov 2012 15:38:57 +0000
  4. Subject: [PATCH] RTC: Added I2C driver for NXP/Philips PCF2127A device from
  5. Eckelmann AG.
  6.  
  7. ---
  8. arch/arm/configs/bcmrpi_defconfig | 1 +
  9. drivers/rtc/Kconfig | 11 ++
  10. drivers/rtc/Makefile | 1 +
  11. drivers/rtc/rtc-pcf2127a.c | 307 ++++++++++++++++++++++++++++++++++++++
  12. 4 files changed, 320 insertions(+)
  13. create mode 100644 drivers/rtc/rtc-pcf2127a.c
  14.  
  15. diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
  16. index b4a3da1..1902263 100644
  17. --- a/arch/arm/configs/bcmrpi_defconfig
  18. +++ b/arch/arm/configs/bcmrpi_defconfig
  19. @@ -784,6 +784,7 @@ CONFIG_RTC_DRV_ISL12022=m
  20. CONFIG_RTC_DRV_X1205=m
  21. CONFIG_RTC_DRV_PCF8563=m
  22. CONFIG_RTC_DRV_PCF8583=m
  23. +CONFIG_RTC_DRV_PCF2127A=m
  24. CONFIG_RTC_DRV_M41T80=m
  25. CONFIG_RTC_DRV_BQ32K=m
  26. CONFIG_RTC_DRV_S35390A=m
  27. diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
  28. index 53eb4e5..201c519 100644
  29. --- a/drivers/rtc/Kconfig
  30. +++ b/drivers/rtc/Kconfig
  31. @@ -271,6 +271,17 @@ config RTC_DRV_PCF8583
  32. This driver can also be built as a module. If so, the module
  33. will be called rtc-pcf8583.
  34.  
  35. +config RTC_DRV_PCF2127A
  36. + tristate "Philips PCF2127A (only I2C)"
  37. + help
  38. + If you say yes here you get support for the Philips PCF2127A
  39. + RTC. This driver implements only the i2c-interface to the chip.
  40. + It may work with pcf2127, but is tested only against
  41. + the pcf2127a.
  42. +
  43. + This driver can also be built as a module. If so, the module
  44. + will be called rtc-pcf2127a.
  45. +
  46. config RTC_DRV_M41T80
  47. tristate "ST M41T62/65/M41T80/81/82/83/84/85/87"
  48. help
  49. diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
  50. index 6e69823..7100c5b 100644
  51. --- a/drivers/rtc/Makefile
  52. +++ b/drivers/rtc/Makefile
  53. @@ -74,6 +74,7 @@ obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o
  54. obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
  55. obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
  56. obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o
  57. +obj-$(CONFIG_RTC_DRV_PCF2127A) += rtc-pcf2127a.o
  58. obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
  59. obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
  60. obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
  61. diff --git a/drivers/rtc/rtc-pcf2127a.c b/drivers/rtc/rtc-pcf2127a.c
  62. new file mode 100644
  63. index 0000000..53ddf31
  64. --- /dev/null
  65. +++ b/drivers/rtc/rtc-pcf2127a.c
  66. @@ -0,0 +1,307 @@
  67. +/*
  68. + * Driver the the NXP/Philips PCF2127A RTC (only I2C)
  69. + *
  70. + * Copyright (c) 2011 ECKELMANN AG.
  71. + *
  72. + * Authors: Matthias Wolf <m.w...@eckelmann.de>
  73. + * Torsten Mehnert <t.me...@eckelmann.de>
  74. + *
  75. + * RTC-Datasheet: http://www.nxp.com/documents/data_sheet/PCF2127A.pdf
  76. + *
  77. + * NOTE: This driver only implements the i2c-interface to the RTC.
  78. + * This driver is based on rtc-pcf8363 from Alessandro Zummo.
  79. + *
  80. + * This program is free software; you can redistribute it and/or modify
  81. + * it under the terms of the GNU General Public License as published by
  82. + * the Free Software Foundation; either version 2 of the License, or
  83. + * (at your option) any later version.
  84. + *
  85. + * This program is distributed in the hope that it will be useful,
  86. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  87. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  88. + * GNU General Public License for more details.
  89. + *
  90. + * You should have received a copy of the GNU General Public License
  91. + * along with this program; if not, write to the Free Software
  92. + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  93. + */
  94. +
  95. +#include <linux/i2c.h>
  96. +#include <linux/bcd.h>
  97. +#include <linux/rtc.h>
  98. +#include <linux/slab.h>
  99. +#include <linux/module.h>
  100. +
  101. +/* PCF2127A Registers */
  102. +#define PCF2127A_REG_CTL1 0x00 /* Control 1 */
  103. +#define PCF2127A_REG_CTL2 0x01 /* Control 2 */
  104. +#define PCF2127A_REG_CTL3 0x02 /* Control 3 */
  105. +
  106. +#define PCF2127A_REG_SC 0x03 /* second value */
  107. +#define PCF2127A_REG_MN 0x04 /* minute value */
  108. +#define PCF2127A_REG_HR 0x05 /* hour value */
  109. +#define PCF2127A_REG_DM 0x06 /* day value */
  110. +#define PCF2127A_REG_DW 0x07 /* weekday value */
  111. +#define PCF2127A_REG_MO 0x08 /* month value */
  112. +#define PCF2127A_REG_YR 0x09 /* year value */
  113. +
  114. +#define PCF2127A_REG_SC_ALARM 0x0A /* second alarm */
  115. +#define PCF2127A_REG_MN_ALARM 0x0B /* minute alarm */
  116. +#define PCF2127A_REG_HR_ALARM 0x0C /* hour alarm */
  117. +#define PCF2127A_REG_DM_ALARM 0x0D /* day alarm */
  118. +#define PCF2127A_REG_DW_ALARM 0x0E /* weekday alarm */
  119. +
  120. +#define PCF2127A_REG_CLKO 0x0F /* clock out */
  121. +#define PCF2127A_REG_WD_TMRC 0x10 /* watchdog timer control */
  122. +#define PCF2127A_REG_WD_TMVAL 0x11 /* watchdog timer value */
  123. +
  124. +#define PCF2127A_REG_TSCTL 0x12 /* timestamp control */
  125. +#define PCF2127A_REG_SC_TS 0x13 /* second timestamp */
  126. +#define PCF2127A_REG_MN_TS 0x14 /* minute timestamp */
  127. +#define PCF2127A_REG_HR_TS 0x15 /* hour timestamp */
  128. +#define PCF2127A_REG_DM_TS 0x16 /* day timestamp */
  129. +#define PCF2127A_REG_MO_TS 0x17 /* month timestamp */
  130. +#define PCF2127A_REG_YR_TS 0x18 /* year timestamp */
  131. +#define PCF2127A_REG_AGI_OFF 0x19 /* aging offset */
  132. +#define PCF2127A_REG_RAM_MSB 0x1A /* RAM address MSB */
  133. +#define PCF2127A_REG_RAM_LSB 0x1B /* RAM address LSB */
  134. +#define PCF2127A_REG_RAM_WCMD 0x1C /* RAM write command */
  135. +#define PCF2127A_REG_RAM_RCMD 0x1D /* RAM read command */
  136. +
  137. +/* Bits in PCF2127A_REG_CTL1 */
  138. +#define PCF2127A_BIT_SI 0x01 /* second interrupt */
  139. +#define PCF2127A_BIT_MI 0x02 /* minute interrupt */
  140. +#define PCF2127A_BIT_H_24_12 0x04 /* 12/24 hour mode */
  141. +#define PCF2127A_BIT_POR_OVRD 0x08 /* POR override */
  142. +#define PCF2127A_BIT_TSF1 0x10 /* timestamp flag 1 */
  143. +#define PCF2127A_BIT_STOP 0x20 /* stop bit */
  144. +#define PCF2127A_BIT_EXTTEST 0x80 /* external clock test mode*/
  145. +
  146. +/* Bits in PCF2127A_REG_CTL2 */
  147. +#define PCF2127A_BIT_CDTIE 0x01 /* countdown timer flag */
  148. +#define PCF2127A_BIT_AIE 0x02 /* alarm interrupt enable */
  149. +#define PCF2127A_BIT_TSIE 0x04 /* timestamp int. enable */
  150. +#define PCF2127A_BIT_CDTF 0x08 /* countdown timer flag */
  151. +#define PCF2127A_BIT_AF 0x10 /* alarm flag */
  152. +#define PCF2127A_BIT_TSF2 0x20 /* timestamp flag 2 */
  153. +#define PCF2127A_BIT_WDTF 0x40 /* watchdog timer flag */
  154. +#define PCF2127A_BIT_MSF 0x80 /* minute/second flag */
  155. +
  156. +/* Bits in PCF2127A_REG_CTL3 */
  157. +#define PCF2127A_BIT_BLIE 0x01 /* battery low Interrupt enable */
  158. +#define PCF2127A_BIT_BIE 0x02 /* battery Switch int. enable */
  159. +#define PCF2127A_BIT_BLF 0x04 /* battery low flag */
  160. +#define PCF2127A_BIT_BF 0x08 /* battery switch flag */
  161. +#define PCF2127A_BIT_BTSE 0x10 /* battery timestamp enable */
  162. +#define PCF2127A_BIT_BLDOFF 0x20 /* battery low detection off */
  163. +#define PCF2127A_BIT_BSM 0x40 /* battery switch mode */
  164. +#define PCF2127A_BIT_BSOFF 0x80 /* battery switch off */
  165. +
  166. +static struct i2c_driver pcf2127a_driver;
  167. +
  168. +/*
  169. + * In the routines that deal directly with the pcf2127a hardware, we use
  170. + * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
  171. + */
  172. +static
  173. +int pcf2127a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
  174. +{
  175. + unsigned char buf[10] = { PCF2127A_REG_CTL1 };
  176. +
  177. + /*
  178. + * Note: We can't use i2c_transfer to send/recv multiple i2c_msg's
  179. + * to/from pcf2127a at once. The reason is that the pcf2127a doesn't
  180. + * handle (repeated START)-Conditions correctly.
  181. + *
  182. + * PCF2127A Manual, Section 9.2.2 START and STOP conditions:
  183. + * "Remark: For the PCF2127A a repeated START is not allowed. Therefore
  184. + * a STOP has to be released before the next START."
  185. + */
  186. +
  187. + /* setup read ptr */
  188. + if (!i2c_master_send(client, buf, 1)) {
  189. + dev_err(&client->dev, "%s: write error\n", __func__);
  190. + return -EIO;
  191. + }
  192. +
  193. + /* read status + date */
  194. + if (!i2c_master_recv(client, buf, 10)) {
  195. + dev_err(&client->dev, "%s: read error\n", __func__);
  196. + return -EIO;
  197. + }
  198. +
  199. + if (buf[PCF2127A_REG_CTL3] & PCF2127A_BIT_BLF)
  200. + dev_info(&client->dev,
  201. + "low battery detected, date/time is not reliable.\n");
  202. +
  203. +#ifdef DEBUG
  204. + unsigned char bf_buf[2];
  205. + if (buf[PCF2127A_REG_CTL3] & PCF2127A_BIT_BF) {
  206. + dev_info(&client->dev,
  207. + "battery switch-over detected - reset BF flag.\n");
  208. +
  209. + bf_buf[0] = PCF2127A_REG_CTL3;
  210. + bf_buf[1] = buf[PCF2127A_REG_CTL3] & ~PCF2127A_BIT_BF;
  211. + if (!i2c_master_send(client, bf_buf, 2)) {
  212. + dev_err(&client->dev,
  213. + "%s: write error\n", __func__);
  214. + return -EIO;
  215. + }
  216. + }
  217. +#endif
  218. +
  219. + dev_dbg(&client->dev,
  220. + "%s: raw data is ctl1=%02x, ctl2=%02x, ctl3=%02x, sec=%02x, "
  221. + "min=%02x, hour=%02x, day=%02x, wday=%02x, month=%02x, "
  222. + "year=%02x\n",
  223. + __func__,
  224. + buf[0], buf[1], buf[2], buf[3],
  225. + buf[4], buf[5], buf[6], buf[7],
  226. + buf[8], buf[9]);
  227. +
  228. + tm->tm_sec = bcd2bin(buf[PCF2127A_REG_SC] & 0x7F);
  229. + tm->tm_min = bcd2bin(buf[PCF2127A_REG_MN] & 0x7F);
  230. + tm->tm_hour = bcd2bin(buf[PCF2127A_REG_HR] & 0x3F); /* rtc hr 0-23 */
  231. + tm->tm_mday = bcd2bin(buf[PCF2127A_REG_DM] & 0x3F);
  232. + tm->tm_wday = buf[PCF2127A_REG_DW] & 0x07;
  233. + tm->tm_mon = bcd2bin(buf[PCF2127A_REG_MO] & 0x1F) - 1; /* rtc m 1-12 */
  234. + tm->tm_year = bcd2bin(buf[PCF2127A_REG_YR]);
  235. +
  236. + if (tm->tm_year < 70)
  237. + tm->tm_year += 100; /* assume we are in 1970...2069 */
  238. +
  239. + /*
  240. + * the clock can give out invalid datetime, but we cannot return
  241. + * -EINVAL otherwise hwclock will refuse to set the time on bootup.
  242. + */
  243. + if (rtc_valid_tm(tm) < 0)
  244. + dev_err(&client->dev, "retrieved date/time is not valid.\n");
  245. +
  246. + return 0;
  247. +}
  248. +
  249. +static
  250. +int pcf2127a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
  251. +{
  252. + int i, err;
  253. + unsigned char msgdata[2]; /* send data*/
  254. + unsigned char buf[10]; /* Index 0 - 9 */
  255. +
  256. + /* hours, minutes and seconds */
  257. + buf[PCF2127A_REG_SC] = bin2bcd(tm->tm_sec);
  258. + buf[PCF2127A_REG_MN] = bin2bcd(tm->tm_min);
  259. + buf[PCF2127A_REG_HR] = bin2bcd(tm->tm_hour);
  260. +
  261. + /* day of month */
  262. + buf[PCF2127A_REG_DM] = bin2bcd(tm->tm_mday);
  263. +
  264. + /* weekday */
  265. + buf[PCF2127A_REG_DW] = tm->tm_wday & 0x07;
  266. +
  267. + /* month, 1 - 12 */
  268. + buf[PCF2127A_REG_MO] = bin2bcd(tm->tm_mon + 1);
  269. +
  270. + /* year */
  271. + buf[PCF2127A_REG_YR] = bin2bcd(tm->tm_year % 100);
  272. +
  273. + /* write register's data */
  274. + for (i = 0; i < 7; i++) {
  275. + msgdata[0] = PCF2127A_REG_SC + i;
  276. + msgdata[1] = buf[PCF2127A_REG_SC + i];
  277. + err = i2c_master_send(client, msgdata, sizeof(msgdata));
  278. + if (err != sizeof(msgdata)) {
  279. + dev_err(&client->dev,
  280. + "%s: err=%d addr=%02x, data=%02x\n",
  281. + __func__, err, msgdata[0], msgdata[1]);
  282. + return -EIO;
  283. + }
  284. + }
  285. + return 0;
  286. +}
  287. +
  288. +/*---------------------------------------------------------------------------*/
  289. +
  290. +static int pcf2127a_rtc_read_time(struct device *dev, struct rtc_time *tm)
  291. +{
  292. + return pcf2127a_get_datetime(to_i2c_client(dev), tm);
  293. +}
  294. +
  295. +static int pcf2127a_rtc_set_time(struct device *dev, struct rtc_time *tm)
  296. +{
  297. + return pcf2127a_set_datetime(to_i2c_client(dev), tm);
  298. +}
  299. +
  300. +static const struct rtc_class_ops pcf2127a_rtc_ops = {
  301. + .read_time = pcf2127a_rtc_read_time,
  302. + .set_time = pcf2127a_rtc_set_time,
  303. +};
  304. +
  305. +/*---------------------------------------------------------------------------*/
  306. +
  307. +static int pcf2127a_probe(struct i2c_client *client,
  308. + const struct i2c_device_id *id)
  309. +{
  310. + struct rtc_device *pcf2127a_device;
  311. +
  312. + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
  313. + return -ENODEV;
  314. +
  315. + dev_info(&client->dev, "chip found\n");
  316. +
  317. + pcf2127a_device = rtc_device_register(pcf2127a_driver.driver.name,
  318. + &client->dev, &pcf2127a_rtc_ops, THIS_MODULE);
  319. +
  320. + if (IS_ERR(pcf2127a_device))
  321. + return PTR_ERR(pcf2127a_device);
  322. +
  323. + i2c_set_clientdata(client, pcf2127a_device);
  324. +
  325. + return 0;
  326. +}
  327. +
  328. +/*---------------------------------------------------------------------------*/
  329. +
  330. +static int pcf2127a_remove(struct i2c_client *client)
  331. +{
  332. + struct rtc_device *pcf2127a_device = i2c_get_clientdata(client);
  333. +
  334. + if (pcf2127a_device)
  335. + rtc_device_unregister(pcf2127a_device);
  336. +
  337. + return 0;
  338. +}
  339. +
  340. +static const struct i2c_device_id pcf2127a_id[] = {
  341. + /*
  342. + * This driver should also work with the pcf2127, but
  343. + * I can't prove it.
  344. + */
  345. + { "pcf2127a", 0 },
  346. + { }
  347. +};
  348. +MODULE_DEVICE_TABLE(i2c, pcf2127a_id);
  349. +
  350. +static struct i2c_driver pcf2127a_driver = {
  351. + .driver = {
  352. + .name = "rtc-pcf2127a",
  353. + },
  354. + .probe = pcf2127a_probe,
  355. + .remove = pcf2127a_remove,
  356. + .id_table = pcf2127a_id,
  357. +};
  358. +
  359. +static int __init pcf2127a_init(void)
  360. +{
  361. + return i2c_add_driver(&pcf2127a_driver);
  362. +}
  363. +module_init(pcf2127a_init);
  364. +
  365. +static void __exit pcf2127a_exit(void)
  366. +{
  367. + i2c_del_driver(&pcf2127a_driver);
  368. +}
  369. +module_exit(pcf2127a_exit);
  370. +
  371. +MODULE_AUTHOR("ECKELMANN AG");
  372. +MODULE_DESCRIPTION("NXP/Philips PCF2127A RTC (I2C) driver");
  373. +MODULE_LICENSE("GPL");
  374. --
  375. 1.8.1.6
Dieser Code wurde in 0.0306 Sekunden mit GeSHi farblich hervorgehoben.

 

Alle Zeiten sind GMT + 1 Stunde
Aktuelles Datum und Uhrzeit: 28.01.2021, 13:05
Nach oben
Valid HTML 4.01 Transitional
Valid CSS!

netcup - Internetdienstleistungen
 
 
[ happytec.at | forum.happytec.at | blog.happytec.at | esports.happytec.at ]