blob: 025a17a95da3195040b70cf1554190e6e7180bba [file] [log] [blame]
Jonghwa Leefca1dd02013-02-21 16:44:26 -08001/*
2 * RTC driver for Maxim MAX77686
3 *
4 * Copyright (C) 2012 Samsung Electronics Co.Ltd
5 *
6 * based on rtc-max8997.c
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
Joe Perchesa737e8352015-04-16 12:46:14 -070015#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
Jonghwa Leefca1dd02013-02-21 16:44:26 -080017#include <linux/slab.h>
18#include <linux/rtc.h>
19#include <linux/delay.h>
20#include <linux/mutex.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/mfd/max77686-private.h>
24#include <linux/irqdomain.h>
25#include <linux/regmap.h>
26
27/* RTC Control Register */
28#define BCD_EN_SHIFT 0
Jingoo Hanac60bf32013-04-29 16:18:31 -070029#define BCD_EN_MASK (1 << BCD_EN_SHIFT)
Jonghwa Leefca1dd02013-02-21 16:44:26 -080030#define MODEL24_SHIFT 1
31#define MODEL24_MASK (1 << MODEL24_SHIFT)
32/* RTC Update Register1 */
33#define RTC_UDR_SHIFT 0
34#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT)
35#define RTC_RBUDR_SHIFT 4
36#define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT)
Jonghwa Leefca1dd02013-02-21 16:44:26 -080037/* RTC Hour register */
38#define HOUR_PM_SHIFT 6
39#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT)
40/* RTC Alarm Enable */
41#define ALARM_ENABLE_SHIFT 7
42#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT)
43
Javier Martinez Canillas59818042016-01-27 00:36:39 -030044#define MAX77686_RTC_UPDATE_DELAY 16000
Jonghwa Leefca1dd02013-02-21 16:44:26 -080045
46enum {
47 RTC_SEC = 0,
48 RTC_MIN,
49 RTC_HOUR,
50 RTC_WEEKDAY,
51 RTC_MONTH,
52 RTC_YEAR,
53 RTC_DATE,
54 RTC_NR_TIME
55};
56
57struct max77686_rtc_info {
58 struct device *dev;
59 struct max77686_dev *max77686;
60 struct i2c_client *rtc;
61 struct rtc_device *rtc_dev;
62 struct mutex lock;
63
64 struct regmap *regmap;
65
66 int virq;
67 int rtc_24hr_mode;
68};
69
70enum MAX77686_RTC_OP {
71 MAX77686_RTC_WRITE,
72 MAX77686_RTC_READ,
73};
74
Jonghwa Leefca1dd02013-02-21 16:44:26 -080075static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm,
76 int rtc_24hr_mode)
77{
78 tm->tm_sec = data[RTC_SEC] & 0x7f;
79 tm->tm_min = data[RTC_MIN] & 0x7f;
80 if (rtc_24hr_mode)
81 tm->tm_hour = data[RTC_HOUR] & 0x1f;
82 else {
83 tm->tm_hour = data[RTC_HOUR] & 0x0f;
84 if (data[RTC_HOUR] & HOUR_PM_MASK)
85 tm->tm_hour += 12;
86 }
87
Javier Martinez Canillasa20cd882014-10-13 15:53:03 -070088 /* Only a single bit is set in data[], so fls() would be equivalent */
89 tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f) - 1;
Jonghwa Leefca1dd02013-02-21 16:44:26 -080090 tm->tm_mday = data[RTC_DATE] & 0x1f;
91 tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
92 tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100;
93 tm->tm_yday = 0;
94 tm->tm_isdst = 0;
95}
96
97static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
98{
99 data[RTC_SEC] = tm->tm_sec;
100 data[RTC_MIN] = tm->tm_min;
101 data[RTC_HOUR] = tm->tm_hour;
102 data[RTC_WEEKDAY] = 1 << tm->tm_wday;
103 data[RTC_DATE] = tm->tm_mday;
104 data[RTC_MONTH] = tm->tm_mon + 1;
Sachin Kamatcdf5f4a2013-07-03 15:05:55 -0700105 data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800106
107 if (tm->tm_year < 100) {
Joe Perchesa737e8352015-04-16 12:46:14 -0700108 pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n",
109 1900 + tm->tm_year);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800110 return -EINVAL;
111 }
112 return 0;
113}
114
115static int max77686_rtc_update(struct max77686_rtc_info *info,
116 enum MAX77686_RTC_OP op)
117{
118 int ret;
119 unsigned int data;
120
121 if (op == MAX77686_RTC_WRITE)
122 data = 1 << RTC_UDR_SHIFT;
123 else
124 data = 1 << RTC_RBUDR_SHIFT;
125
126 ret = regmap_update_bits(info->max77686->rtc_regmap,
127 MAX77686_RTC_UPDATE0, data, data);
128 if (ret < 0)
129 dev_err(info->dev, "%s: fail to write update reg(ret=%d, data=0x%x)\n",
130 __func__, ret, data);
131 else {
132 /* Minimum 16ms delay required before RTC update. */
Javier Martinez Canillas59818042016-01-27 00:36:39 -0300133 usleep_range(MAX77686_RTC_UPDATE_DELAY,
134 MAX77686_RTC_UPDATE_DELAY * 2);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800135 }
136
137 return ret;
138}
139
140static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm)
141{
142 struct max77686_rtc_info *info = dev_get_drvdata(dev);
143 u8 data[RTC_NR_TIME];
144 int ret;
145
146 mutex_lock(&info->lock);
147
148 ret = max77686_rtc_update(info, MAX77686_RTC_READ);
149 if (ret < 0)
150 goto out;
151
152 ret = regmap_bulk_read(info->max77686->rtc_regmap,
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300153 MAX77686_RTC_SEC, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800154 if (ret < 0) {
155 dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, ret);
156 goto out;
157 }
158
159 max77686_rtc_data_to_tm(data, tm, info->rtc_24hr_mode);
160
161 ret = rtc_valid_tm(tm);
162
163out:
164 mutex_unlock(&info->lock);
165 return ret;
166}
167
168static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm)
169{
170 struct max77686_rtc_info *info = dev_get_drvdata(dev);
171 u8 data[RTC_NR_TIME];
172 int ret;
173
174 ret = max77686_rtc_tm_to_data(tm, data);
175 if (ret < 0)
176 return ret;
177
178 mutex_lock(&info->lock);
179
180 ret = regmap_bulk_write(info->max77686->rtc_regmap,
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300181 MAX77686_RTC_SEC, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800182 if (ret < 0) {
183 dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__,
184 ret);
185 goto out;
186 }
187
188 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
189
190out:
191 mutex_unlock(&info->lock);
192 return ret;
193}
194
195static int max77686_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
196{
197 struct max77686_rtc_info *info = dev_get_drvdata(dev);
198 u8 data[RTC_NR_TIME];
199 unsigned int val;
200 int i, ret;
201
202 mutex_lock(&info->lock);
203
204 ret = max77686_rtc_update(info, MAX77686_RTC_READ);
205 if (ret < 0)
206 goto out;
207
208 ret = regmap_bulk_read(info->max77686->rtc_regmap,
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300209 MAX77686_ALARM1_SEC, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800210 if (ret < 0) {
211 dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n",
212 __func__, __LINE__, ret);
213 goto out;
214 }
215
216 max77686_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
217
218 alrm->enabled = 0;
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300219 for (i = 0; i < ARRAY_SIZE(data); i++) {
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800220 if (data[i] & ALARM_ENABLE_MASK) {
221 alrm->enabled = 1;
222 break;
223 }
224 }
225
226 alrm->pending = 0;
Sangjung Woo1748cbf2013-09-11 14:24:21 -0700227 ret = regmap_read(info->max77686->regmap, MAX77686_REG_STATUS2, &val);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800228 if (ret < 0) {
Sangjung Woo1748cbf2013-09-11 14:24:21 -0700229 dev_err(info->dev, "%s:%d fail to read status2 reg(%d)\n",
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800230 __func__, __LINE__, ret);
231 goto out;
232 }
233
234 if (val & (1 << 4)) /* RTCA1 */
235 alrm->pending = 1;
236
237out:
238 mutex_unlock(&info->lock);
Javier Martinez Canillas7cdffeb2016-01-27 00:36:37 -0300239 return ret;
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800240}
241
242static int max77686_rtc_stop_alarm(struct max77686_rtc_info *info)
243{
244 u8 data[RTC_NR_TIME];
245 int ret, i;
246 struct rtc_time tm;
247
248 if (!mutex_is_locked(&info->lock))
249 dev_warn(info->dev, "%s: should have mutex locked\n", __func__);
250
251 ret = max77686_rtc_update(info, MAX77686_RTC_READ);
252 if (ret < 0)
253 goto out;
254
255 ret = regmap_bulk_read(info->max77686->rtc_regmap,
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300256 MAX77686_ALARM1_SEC, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800257 if (ret < 0) {
258 dev_err(info->dev, "%s: fail to read alarm reg(%d)\n",
259 __func__, ret);
260 goto out;
261 }
262
263 max77686_rtc_data_to_tm(data, &tm, info->rtc_24hr_mode);
264
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300265 for (i = 0; i < ARRAY_SIZE(data); i++)
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800266 data[i] &= ~ALARM_ENABLE_MASK;
267
268 ret = regmap_bulk_write(info->max77686->rtc_regmap,
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300269 MAX77686_ALARM1_SEC, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800270 if (ret < 0) {
271 dev_err(info->dev, "%s: fail to write alarm reg(%d)\n",
272 __func__, ret);
273 goto out;
274 }
275
276 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
277out:
278 return ret;
279}
280
281static int max77686_rtc_start_alarm(struct max77686_rtc_info *info)
282{
283 u8 data[RTC_NR_TIME];
284 int ret;
285 struct rtc_time tm;
286
287 if (!mutex_is_locked(&info->lock))
288 dev_warn(info->dev, "%s: should have mutex locked\n", __func__);
289
290 ret = max77686_rtc_update(info, MAX77686_RTC_READ);
291 if (ret < 0)
292 goto out;
293
294 ret = regmap_bulk_read(info->max77686->rtc_regmap,
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300295 MAX77686_ALARM1_SEC, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800296 if (ret < 0) {
297 dev_err(info->dev, "%s: fail to read alarm reg(%d)\n",
298 __func__, ret);
299 goto out;
300 }
301
302 max77686_rtc_data_to_tm(data, &tm, info->rtc_24hr_mode);
303
304 data[RTC_SEC] |= (1 << ALARM_ENABLE_SHIFT);
305 data[RTC_MIN] |= (1 << ALARM_ENABLE_SHIFT);
306 data[RTC_HOUR] |= (1 << ALARM_ENABLE_SHIFT);
307 data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK;
308 if (data[RTC_MONTH] & 0xf)
309 data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT);
310 if (data[RTC_YEAR] & 0x7f)
311 data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT);
312 if (data[RTC_DATE] & 0x1f)
313 data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT);
314
315 ret = regmap_bulk_write(info->max77686->rtc_regmap,
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300316 MAX77686_ALARM1_SEC, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800317 if (ret < 0) {
318 dev_err(info->dev, "%s: fail to write alarm reg(%d)\n",
319 __func__, ret);
320 goto out;
321 }
322
323 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
324out:
325 return ret;
326}
327
328static int max77686_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
329{
330 struct max77686_rtc_info *info = dev_get_drvdata(dev);
331 u8 data[RTC_NR_TIME];
332 int ret;
333
334 ret = max77686_rtc_tm_to_data(&alrm->time, data);
335 if (ret < 0)
336 return ret;
337
338 mutex_lock(&info->lock);
339
340 ret = max77686_rtc_stop_alarm(info);
341 if (ret < 0)
342 goto out;
343
344 ret = regmap_bulk_write(info->max77686->rtc_regmap,
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300345 MAX77686_ALARM1_SEC, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800346
347 if (ret < 0) {
348 dev_err(info->dev, "%s: fail to write alarm reg(%d)\n",
349 __func__, ret);
350 goto out;
351 }
352
353 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
354 if (ret < 0)
355 goto out;
356
357 if (alrm->enabled)
358 ret = max77686_rtc_start_alarm(info);
359out:
360 mutex_unlock(&info->lock);
361 return ret;
362}
363
364static int max77686_rtc_alarm_irq_enable(struct device *dev,
365 unsigned int enabled)
366{
367 struct max77686_rtc_info *info = dev_get_drvdata(dev);
368 int ret;
369
370 mutex_lock(&info->lock);
371 if (enabled)
372 ret = max77686_rtc_start_alarm(info);
373 else
374 ret = max77686_rtc_stop_alarm(info);
375 mutex_unlock(&info->lock);
376
377 return ret;
378}
379
380static irqreturn_t max77686_rtc_alarm_irq(int irq, void *data)
381{
382 struct max77686_rtc_info *info = data;
383
384 dev_info(info->dev, "%s:irq(%d)\n", __func__, irq);
385
386 rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
387
388 return IRQ_HANDLED;
389}
390
391static const struct rtc_class_ops max77686_rtc_ops = {
392 .read_time = max77686_rtc_read_time,
393 .set_time = max77686_rtc_set_time,
394 .read_alarm = max77686_rtc_read_alarm,
395 .set_alarm = max77686_rtc_set_alarm,
396 .alarm_irq_enable = max77686_rtc_alarm_irq_enable,
397};
398
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800399static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
400{
401 u8 data[2];
402 int ret;
403
404 /* Set RTC control register : Binary mode, 24hour mdoe */
405 data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
406 data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
407
408 info->rtc_24hr_mode = 1;
409
Javier Martinez Canillas862f9452016-01-27 00:36:38 -0300410 ret = regmap_bulk_write(info->max77686->rtc_regmap,
411 MAX77686_RTC_CONTROLM, data, ARRAY_SIZE(data));
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800412 if (ret < 0) {
413 dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
414 __func__, ret);
415 return ret;
416 }
417
418 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
419 return ret;
420}
421
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800422static int max77686_rtc_probe(struct platform_device *pdev)
423{
424 struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent);
425 struct max77686_rtc_info *info;
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200426 int ret;
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800427
Jingoo Han3cebeb52013-02-21 16:45:24 -0800428 dev_info(&pdev->dev, "%s\n", __func__);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800429
Jingoo Han0f64f852013-04-29 16:18:30 -0700430 info = devm_kzalloc(&pdev->dev, sizeof(struct max77686_rtc_info),
431 GFP_KERNEL);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800432 if (!info)
433 return -ENOMEM;
434
435 mutex_init(&info->lock);
436 info->dev = &pdev->dev;
437 info->max77686 = max77686;
438 info->rtc = max77686->rtc;
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200439
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800440 platform_set_drvdata(pdev, info);
441
442 ret = max77686_rtc_init_reg(info);
443
444 if (ret < 0) {
445 dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret);
446 goto err_rtc;
447 }
448
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800449 device_init_wakeup(&pdev->dev, 1);
450
Jingoo Hanf56950e2013-04-29 16:19:05 -0700451 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc",
452 &max77686_rtc_ops, THIS_MODULE);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800453
454 if (IS_ERR(info->rtc_dev)) {
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800455 ret = PTR_ERR(info->rtc_dev);
456 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
457 if (ret == 0)
458 ret = -EINVAL;
459 goto err_rtc;
460 }
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200461
Javier Martinez Canillas1745d6d2014-10-13 15:52:59 -0700462 if (!max77686->rtc_irq_data) {
463 ret = -EINVAL;
464 dev_err(&pdev->dev, "%s: no RTC regmap IRQ chip\n", __func__);
465 goto err_rtc;
466 }
467
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200468 info->virq = regmap_irq_get_virq(max77686->rtc_irq_data,
469 MAX77686_RTCIRQ_RTCA1);
470 if (!info->virq) {
Sachin Kamatad819032013-04-29 16:20:12 -0700471 ret = -ENXIO;
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800472 goto err_rtc;
Sachin Kamatad819032013-04-29 16:20:12 -0700473 }
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800474
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200475 ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL,
476 max77686_rtc_alarm_irq, 0, "rtc-alarm1", info);
Sachin Kamatad819032013-04-29 16:20:12 -0700477 if (ret < 0)
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800478 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
479 info->virq, ret);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800480
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800481err_rtc:
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800482 return ret;
483}
484
Doug Andersone7f7fc72014-10-13 15:52:55 -0700485#ifdef CONFIG_PM_SLEEP
486static int max77686_rtc_suspend(struct device *dev)
487{
488 if (device_may_wakeup(dev)) {
489 struct max77686_rtc_info *info = dev_get_drvdata(dev);
490
491 return enable_irq_wake(info->virq);
492 }
493
494 return 0;
495}
496
497static int max77686_rtc_resume(struct device *dev)
498{
499 if (device_may_wakeup(dev)) {
500 struct max77686_rtc_info *info = dev_get_drvdata(dev);
501
502 return disable_irq_wake(info->virq);
503 }
504
505 return 0;
506}
507#endif
508
509static SIMPLE_DEV_PM_OPS(max77686_rtc_pm_ops,
510 max77686_rtc_suspend, max77686_rtc_resume);
511
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800512static const struct platform_device_id rtc_id[] = {
513 { "max77686-rtc", 0 },
514 {},
515};
Javier Martinez Canillas2d0cca02015-05-13 17:18:01 +0200516MODULE_DEVICE_TABLE(platform, rtc_id);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800517
518static struct platform_driver max77686_rtc_driver = {
519 .driver = {
520 .name = "max77686-rtc",
Doug Andersone7f7fc72014-10-13 15:52:55 -0700521 .pm = &max77686_rtc_pm_ops,
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800522 },
523 .probe = max77686_rtc_probe,
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800524 .id_table = rtc_id,
525};
526
Jingoo Han0c58ff52013-04-29 16:18:28 -0700527module_platform_driver(max77686_rtc_driver);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800528
529MODULE_DESCRIPTION("Maxim MAX77686 RTC driver");
Jingoo Hanf5b1d3c2013-04-29 16:18:29 -0700530MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>");
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800531MODULE_LICENSE("GPL");