找回密码
 注册
关于网站域名变更的通知
查看: 602|回复: 2
打印 上一主题 下一主题

【问题】4412开发板配置pcf8563时钟芯片驱动后,无法使用,是什么问题呢?

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2017-8-28 15:31 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

2 r2 @. F1 T4 O. _# L  b1 o
开发板:
各位版主、工程师们你们好:
      请教你们一些问题:
             1)在内核中配置pcf8563时钟芯片启动完成,内核启动后 /dev/rtc/ 中没有pcf8563芯片对应的 rtc 节点;
             2)内核启动过程中打印 drivers/rtc/hctosys.c: unable to open rtc device (rtc0);
             3)pcf8563芯片驱动程序的 pcf8563_probe()在整个启动过程中没有被执行;
             4)请问这是怎么回事?该怎么修改???
             5)驱动程序代码如下:
驱动代码:
7 J6 c8 F) K2 ^& ^
#include <linux/i2c.h>
. N( c9 n0 I/ P& N: K0 s
#include <linux/bcd.h>0 O3 j' d  B: C9 c9 k) P2 y) m
#include <linux/rtc.h>  h9 ~; n7 w! q  a
#include <linux/slab.h>+ N( p" P; t* S. C0 \( G: {

) ?# M$ F$ R3 O. A0 D
#define DRV_VERSION "0.4.3"& }  N  [" [4 R8 K! F
5 S6 K; U9 k  D% l- t3 l
#define PCF8563_REG_ST1                0x00 /* status */
8 t( _$ p* G& Q, m: ]8 e
#define PCF8563_REG_ST2                0x01+ g' O: r7 c9 Z7 q# Z# e9 m

% e( O+ R% ]0 Q; R2 ^. x- i
#define PCF8563_REG_SC                0x02 /* datetime */. k4 G/ K/ V2 Q  c! v2 ?  U
#define PCF8563_REG_MN                0x03
1 n. e2 o0 k# i; h0 D* M9 p  L  B
#define PCF8563_REG_HR                0x044 K% |# n5 @8 V$ ~
#define PCF8563_REG_DM                0x05
$ U3 V# Q/ U" j4 J) |
#define PCF8563_REG_DW                0x06) Z& c. @, e1 T
#define PCF8563_REG_MO                0x07
/ b0 |8 ~- T1 z% Y& K! b4 K1 A
#define PCF8563_REG_YR                0x080 i7 E' v0 P' a3 q. c
% |) Y8 g* r+ P; A8 g+ ]) q7 `6 y
#define PCF8563_REG_AMN                0x09 /* alARM */* S, b# O: c. }0 b8 _* q
#define PCF8563_REG_AHR                0x0A
9 e  y; O* v8 i+ F2 H3 e# b' a
#define PCF8563_REG_ADM                0x0B! \) I5 a* b. a  {
#define PCF8563_REG_ADW                0x0C+ v3 @3 K3 d) K- u; k1 D/ f

  Z$ D  Z) f  \% }2 {# G. w
#define PCF8563_REG_CLKO        0x0D /* clock out */1 m' a: U3 Y' Y) d+ ]
#define PCF8563_REG_TMRC        0x0E /* timer control */0 L  C, k) |/ B
#define PCF8563_REG_TMR                0x0F /* timer */" C1 ^! J/ ?1 Y7 `8 ]+ U% R
$ l" v, V2 {" d: z
#define PCF8563_SC_LV                0x80 /* low voltage */
- \) ^9 \# x7 {$ @- T
#define PCF8563_MO_C                0x80 /* century */  _( C, P( ^0 O$ g+ a# R

/ M: e0 D, A. P7 _( i+ j5 _
static struct i2c_driver pcf8563_driver;
5 s* O6 W1 Z' m6 n" e6 D

, M) i$ r3 n! B- r2 c% S$ @' p
struct pcf8563 {6 o& k9 b% T% t3 d$ J9 e
        struct rtc_device *rtc;
" j( d$ B8 L( U) E+ S
        /*  U  J* E; P9 c. T& c
         * The meaning of MO_C bit varies by the chip type.. d4 T% {/ ~$ _$ T# f
         * From PCF8563 datasheet: this bit is toggled when the years
$ S- f4 r' E, T3 O
         * register oveRFlows from 99 to 004 H  x6 |* m% Q2 G) X( Y! V4 L
         *   0 indicates the century is 20xx' P) I  r+ |( s) e/ M8 H
         *   1 indicates the century is 19xx; `+ Y2 o, I4 X9 m: x3 X; ]( s
         * From RTC8564 datasheet: this bit indicates change of
9 V# H  e6 L+ Z  w( Q( o
         * century. When the year digit data overflows from 99 to 00,: \: M2 f5 N) O% r
         * this bit is set. By presetting it to 0 while still in the/ n) e) K" Z/ M) n  ]/ O+ [
         * 20th century, it will be set in year 2000, ...# q9 ~2 X. t) f+ i' L! @
         * There seems no reliable way to know how the system use this/ ^: ]/ O7 D" h+ x. l% T. W
         * bit.  So let's do it heuristically, assuming we are live in6 F/ @2 J8 a7 |, ~
         * 1970...2069.
) K. X# ^1 Z8 y' t. Y2 T
         */
' b/ y9 ~: b: ?4 h
        int c_polarity;        /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
5 \' l$ z) M) p4 g' z* \2 s
};
( K$ u7 z& a' }' i: c$ j% }5 l
" `$ y8 l8 ]0 m" j; Z* ^
/*, ?2 h( Y$ n  Z& J9 ^7 [
* In the routines that deal directly with the pcf8563 hardware, we use- ?3 t. G8 d- b: [4 w
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
. T' f- W. a' U# L. w1 z
*/# q2 n) q- y' b+ o- A0 ?
static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
, `! l0 x/ h! G4 y
{( J' h+ h) a. |. z
        struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
+ i8 A% V7 `0 A+ B6 D' g3 L
        unsigned char buf[13] = { PCF8563_REG_ST1 };$ \) Q$ E# A9 ^. Z6 [8 p

' W; U6 J! D  U9 L/ ]% }
        struct i2c_msg msgs[] = {0 T" W' _& d* G& z9 d6 Q! h
                { client->addr, 0, 1, buf },        /* setup read ptr */
# _; H; }  H! d9 r( |
                { client->addr, I2C_M_RD, 13, buf },        /* read status + date */; X% H- M0 b; c" N% N5 s
        };
$ g1 d8 B- C* {# N( i$ S" _

+ y+ ~- r" F) R) I
        /* read registers */
) Q  h1 E8 p: u0 ?
        if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
6 l6 n8 l9 z- Z% P
                dev_err(&client->dev, "%s: read error\n", __func__);2 W0 |6 n) g) e  L
                return -EIO;* M# w: L0 Y* }! y' @2 B
        }
9 I$ e$ t1 |: U0 t9 A: P9 F- W

3 q0 P. G' [: |; h
        if (buf[PCF8563_REG_SC] & PCF8563_SC_LV)5 g) h* M. Y) R" s$ j# O( U
                dev_info(&client->dev,/ n- i$ P, [' S' ~; g3 S: D
                        "low voltage detected, date/time is not reliable.\n");2 X; q1 Q4 y$ F) `4 h' n& X

$ t' s, A- [2 \
        dev_dbg(&client->dev,4 n3 _! w. H5 U, V: h# \
                "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, "
* l6 i, T: W/ N& z2 e4 v
                "mday=%02x, wday=%02x, mon=%02x, year=%02x\n",2 p1 B0 [3 I5 N
                __func__,& E( M* W( X8 p' J1 i% g
                buf[0], buf[1], buf[2], buf[3],- S4 J5 t, I  n
                buf[4], buf[5], buf[6], buf[7],  ^/ u0 j& K* N
                buf[8]);% ~/ Q& W. U; _2 L4 K0 y

4 ]4 p$ b% ]2 k/ v0 ^$ K
6 ]3 W& d( ~( U, ]. \
        tm->tm_sec = bcd2bin(buf[PCF8563_REG_SC] & 0x7F);
: I/ K  v; |9 V+ \- Z9 s& A7 |
        tm->tm_min = bcd2bin(buf[PCF8563_REG_MN] & 0x7F);
: [9 A0 J$ z/ L  I+ o* |4 G- [
        tm->tm_hour = bcd2bin(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */
! e3 @4 z8 k5 U6 @8 s1 y+ l
        tm->tm_mday = bcd2bin(buf[PCF8563_REG_DM] & 0x3F);
# A8 Q( ?1 K. w0 |7 Y
        tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
) l- n; c5 S6 e# `" k3 O# O8 J
        tm->tm_mon = bcd2bin(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
& K4 H4 ^- P, A8 g. \) e* d
        tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]);1 W% H5 ^  ]0 K* |: ^1 B# b" H- U
        if (tm->tm_year < 70)
" [' f3 K* t. c
                tm->tm_year += 100;        /* assume we are in 1970...2069 */
  p+ C! k+ P+ l, Q  o
        /* detect the polarity heuristically. see note above. *// G+ L7 t' f- A" O0 Q# d
        pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ?
- |3 R( z* Z$ F
                (tm->tm_year >= 100) : (tm->tm_year < 100);
  e: P; Y  [& L5 |
6 H2 p" j1 ~- A4 F
        dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
$ b8 n) a$ p$ @6 ~% ^. M
                "mday=%d, mon=%d, year=%d, wday=%d\n",) p$ m9 P) v6 i- E0 _: o$ k( H
                __func__,2 y2 r4 p, k3 K' |' V, a. [- v: w
                tm->tm_sec, tm->tm_min, tm->tm_hour,
$ u( P, z7 z0 b0 g5 ~3 d% W! |
                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
) r2 E1 V% t  }; l0 j1 q

* C  B  |& T+ }0 }
        /* the clock can give out invalid datetime, but we cannot return# {" f) I  Y* K' N9 Y  g8 G
         * -EINVAL otherwise hwclock will refuse to set the time on bootup.+ p& _& T! }" \* B( ?4 w
         */$ w! N$ d) D3 }) O
        if (rtc_valid_tm(tm) < 0)
* H5 D& {& T) V  ]8 l. k) Y9 @6 g+ K1 H
                dev_err(&client->dev, "retrieved date/time is not valid.\n");6 B" r; ~8 s( W' {
# }( f( A8 Q8 M' _" u6 U
        return 0;
( A3 L% L  Q1 c7 f' d
}! X+ o* i& T5 Z5 k+ T. q1 f

0 ^% V6 y1 k* e" W2 F( y& u
static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)/ |1 k8 S1 B  H' z! x3 j
{, j3 j7 u" B$ ]0 D
        struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
" Z4 B' U/ r, B- K5 x, Q9 R
        int i, err;6 H. j/ ~7 x# m& U" T- E' S7 ?/ b
        unsigned char buf[9];
8 l. G4 h: ]+ ^& ~& N. P( [
- c) O  _* ?1 f4 n- x
        dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "  r. ^" [, G3 z  B# P) X1 `: l
                "mday=%d, mon=%d, year=%d, wday=%d\n",
! {! x  ^; H8 ^0 E$ _9 O3 N
                __func__,
* ]4 @, O( K# `" k# S! d
                tm->tm_sec, tm->tm_min, tm->tm_hour,
5 o6 |, u3 T! i9 i( V. j, u1 Y
                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
1 o1 G7 t+ j: ?: f5 k
) S6 w% d3 O* A
        /* hours, minutes and seconds */. \$ ~, D! _  i" ^% Q# f& w
        buf[PCF8563_REG_SC] = bin2bcd(tm->tm_sec);
! Y% o2 P3 e  o! z$ C) d/ E9 J
        buf[PCF8563_REG_MN] = bin2bcd(tm->tm_min);* B- V0 n, T& W$ R: d/ Y3 `  e
        buf[PCF8563_REG_HR] = bin2bcd(tm->tm_hour);
2 i8 g" A- T, [0 A/ t

6 m* `8 C/ G; d- a
        buf[PCF8563_REG_DM] = bin2bcd(tm->tm_mday);$ s: m* N, n3 H

; M) ]/ ^# s; Q( O$ s2 C/ ?* x
        /* month, 1 - 12 */1 k& n7 `2 h4 G$ c7 e
        buf[PCF8563_REG_MO] = bin2bcd(tm->tm_mon + 1);" y' }/ v' K& T) o9 p4 `

- l3 {8 h/ d3 f1 z4 J3 j* |
        /* year and century */0 v" C1 k) E+ w+ T  b, q5 B0 R
        buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year % 100);
! M5 m; q9 m4 G* m( a
        if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
6 B; U" w  u  f) e; F
                buf[PCF8563_REG_MO] |= PCF8563_MO_C;
' z- u0 J, F3 F( ^

. l# |( a  r! ]$ x7 G) j  G
        buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
) v7 X& d- Q) s; S

( l! w" C, @- z5 B" l' F
        /* write register's data */
# ^% M  \+ X5 U$ t
        for (i = 0; i < 7; i++) {9 f& v/ L4 T$ P" ?! H! j
                unsigned char data[2] = { PCF8563_REG_SC + i,
; ~; a8 L/ H% N( E: K
                                                buf[PCF8563_REG_SC + i] };
0 L0 s1 `8 b6 H6 Y% D1 a9 W

$ s, t, ]# J$ y4 R6 W7 l# [
                err = i2c_master_send(client, data, sizeof(data));0 |& R9 p2 Q! q8 B( B0 Y
                if (err != sizeof(data)) {
, v; P/ K9 N) N- T2 S
                        dev_err(&client->dev,! _4 w' k5 ?- E
                                "%s: err=%d addr=%02x, data=%02x\n",' m! H  e1 w1 {2 ?* _
                                __func__, err, data[0], data[1]);2 ~& ?$ O6 H, n8 B2 o* s
                        return -EIO;2 @/ ^6 g0 X2 F% ]1 a
                }9 L- H6 M' y$ x% N, ?; {8 S
        };4 E4 c  Y( H3 g) D
9 P7 N6 u; T/ F- }) l2 z
        return 0;, H! a* A/ P/ i; i
}. k- y: [! M: y6 G5 O- t$ g: Q; f
6 h/ {- f' [. A, }& t" L
static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
5 Y8 n% g; ]  P8 M- G# \
{2 Z0 m5 d. W/ `* @/ i
        return pcf8563_get_datetime(to_i2c_client(dev), tm);/ t% j3 q1 [" h1 ~5 Y4 t
}2 M; A* X- T! I

* q0 H' K% k6 a0 N& g3 v
static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)% u* Z1 \  _" i) A% n/ [: X. g
{
" h3 K" c' ~& K: M. y4 B
        return pcf8563_set_datetime(to_i2c_client(dev), tm);
1 m, Q. H4 k4 K. I6 m
}
/ H# O4 C+ s0 k% e& R2 l8 }5 a/ o5 c8 e

1 x+ d8 A1 @; Y6 H0 g4 e8 c& X" E
static const struct rtc_class_ops pcf8563_rtc_ops = {
- K& B- ~3 {0 S5 I. Q% H
        .read_time        = pcf8563_rtc_read_time,! H0 @" L7 g0 |( M8 A( R; O3 Y
        .set_time        = pcf8563_rtc_set_time,
/ r- V; T; c5 ^* m" ]9 u3 v- ]5 x
};
4 d* F/ ?/ Y' Z3 P/ F! X
: x5 i0 J) }' U, H; w* X, Z0 e
static int pcf8563_probe(struct i2c_client *client,
. |4 c) m8 ~' w' N
                                const struct i2c_device_id *id)
' w' Z& ^: ^  Y, F
{
: K% ~$ @% ^: G; }
        struct pcf8563 *pcf8563;& S9 `/ k! N' f! H3 {
6 w  |% m5 D; Q
        int err = 0;- M! R1 P  B) w
: O8 l+ H( w( b
        dev_dbg(&client->dev, "%s\n", __func__);
( g* D  G! M- Z/ \+ _1 J. U
3 }6 \; ]" m; D
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))' g0 O$ u2 Q, F" p- V
                return -ENODEV;
2 L! V" `( b% x# `
+ L# a$ j+ f4 x% D6 M$ \
        pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL);$ T0 e! b% h; ~! \2 K: W, B
        if (!pcf8563)
( j8 r6 s4 [$ }5 A9 t/ b: j' Q/ x% S
                return -ENOMEM;5 D1 c' h# f4 g3 U5 W
) s! e9 S% e# K- F* L" J
        dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");+ }" _' i* }$ f

4 a. {7 k! F( o* c2 ^5 w* V
        i2c_set_clientdata(client, pcf8563);
0 ?% N, e# i# N) {
( B7 }3 y' Y0 ]0 U3 Q, ^+ j
        pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name,
7 L  v3 \5 ]! I
                                &client->dev, &pcf8563_rtc_ops, THIS_MODULE);4 V9 J4 n) G  k$ x7 n5 ^) B

& U# ]& f; G9 [- _( ]& Y' J, \
        if (IS_ERR(pcf8563->rtc)) {- q5 _# a6 z2 x; I' j4 @
                err = PTR_ERR(pcf8563->rtc);: A! E+ e" V/ J. C2 z  d
                goto exit_kfree;# N# Y: y- F  K  D) }- P
        }
$ `1 W0 F! }8 U: c+ h

# s5 F7 ~8 P: \% ]
        return 0;# h2 ~$ v6 Z. {# _

3 i7 C3 N# q3 G* F
exit_kfree:
, c; `/ q( S( T' @* n
        kfree(pcf8563);7 I: H: G! D# q% y

& L, ?0 F0 s, l9 s9 W# Y# a9 M
        return err;
! C# ?, l4 @2 ]7 }
}
9 p% ~% x4 {6 ?6 z& C( w
, t2 O! c% g& |' R( w; C
static int pcf8563_remove(struct i2c_client *client)  B# `5 M; _! V$ h
{% n. _6 u& l& n- @: V! S; m
        struct pcf8563 *pcf8563 = i2c_get_clientdata(client);, o- W1 }) D$ x1 v, Z3 _
! Z8 D2 t0 b- D6 }
        if (pcf8563->rtc)
* a$ U6 k( B* f  H5 \  [
                rtc_device_unregister(pcf8563->rtc);
+ z! W; A" K: G

0 i/ [* Q* c  A6 D; `; k* w$ m
        kfree(pcf8563);3 m- A; O: a/ I) p' M) c& x

# s; g2 ~# i0 o* y
        return 0;
0 m9 e; y, z) X7 Z* X* X
}; h) \5 _1 \& D2 u/ j

* h3 g, D9 l& U' Q5 }3 h
static const struct i2c_device_id pcf8563_id[] = {3 ^# C, Z, G5 k7 H/ h* h
        { "pcf8563", 0 },0 @* S+ g; z3 v
        { "rtc8564", 0 },$ R0 @* ]7 G& g, n  D: n6 |
        { }
: J8 ]( N# h8 R5 ?1 ~
};& K8 n; w& Y$ L
MODULE_DEVICE_TABLE(i2c, pcf8563_id);
. c5 L6 z* k4 J4 P

$ B# I+ u9 U% x; {+ r) u2 E
static struct i2c_driver pcf8563_driver = {
1 O# c4 C  ?$ I0 I  T$ U2 l
        .driver                = {
/ S- q9 p7 _3 p  x
                .name        = "rtc-pcf8563",- K0 d+ L$ p: N7 Q9 J+ Q
        },
" z! I% {2 q3 H; {
        .probe                = pcf8563_probe,, G6 g+ d" j- n1 t( G$ \$ G+ l
        .remove                = pcf8563_remove,
1 {% G+ P9 ]- V, s" r
        .id_table        = pcf8563_id,3 q2 P# }6 L1 o/ [( f2 s
};+ S: C6 i2 ~; K4 F2 k0 ]

# d* J, w& g' c" _" W1 ~0 [* G$ \  Q
static int __init pcf8563_init(void)
- h! O3 S0 U6 ^% a
{2 F& x; W  l$ C. {: T; T
        return i2c_add_driver(&pcf8563_driver);% y9 [( x- T/ @
}
7 ~( g6 K) ~8 c% z6 q; v3 N

% X+ q/ [( d7 m4 b
static void __exit pcf8563_exit(void)
% U, }; c" v; ^
{0 q5 w9 _, E1 I+ V- q3 f6 x
        i2c_del_driver(&pcf8563_driver);$ G# v0 g9 x0 M/ V7 n
}1 B1 J& r+ ]5 Q; T  R& m; v* ~) w

! z* m4 B- y- L1 s- X  e* o1 v& R; o
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");8 m7 N  l; n4 X; A. Z# F, P
MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
  t$ h9 Z6 N* q- q) ]  ]
MODULE_LICENSE("GPL");& p. M6 X9 T  k6 Y
MODULE_VERSION(DRV_VERSION);
+ M' s: b% u& A

& g8 y# E. ]6 X
module_init(pcf8563_init);
( |- O2 N( S, O
module_exit(pcf8563_exit);

+ t! U$ g' N' K$ N# C

该用户从未签到

3#
发表于 2017-11-25 20:27 | 只看该作者
哪个正常的人能崇拜一只蟑螂呢?

该用户从未签到

2#
发表于 2017-11-24 10:47 | 只看该作者
这么一堆,看蒙了,不过还是了解一下下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-24 12:40 , Processed in 0.187500 second(s), 27 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表