OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [phy/] [davicom.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * drivers/net/phy/davicom.c
3
 *
4
 * Driver for Davicom PHYs
5
 *
6
 * Author: Andy Fleming
7
 *
8
 * Copyright (c) 2004 Freescale Semiconductor, Inc.
9
 *
10
 * This program is free software; you can redistribute  it and/or modify it
11
 * under  the terms of  the GNU General  Public License as published by the
12
 * Free Software Foundation;  either version 2 of the  License, or (at your
13
 * option) any later version.
14
 *
15
 */
16
#include <linux/kernel.h>
17
#include <linux/string.h>
18
#include <linux/errno.h>
19
#include <linux/unistd.h>
20
#include <linux/slab.h>
21
#include <linux/interrupt.h>
22
#include <linux/init.h>
23
#include <linux/delay.h>
24
#include <linux/netdevice.h>
25
#include <linux/etherdevice.h>
26
#include <linux/skbuff.h>
27
#include <linux/spinlock.h>
28
#include <linux/mm.h>
29
#include <linux/module.h>
30
#include <linux/mii.h>
31
#include <linux/ethtool.h>
32
#include <linux/phy.h>
33
 
34
#include <asm/io.h>
35
#include <asm/irq.h>
36
#include <asm/uaccess.h>
37
 
38
#define MII_DM9161_SCR          0x10
39
#define MII_DM9161_SCR_INIT     0x0610
40
 
41
/* DM9161 Interrupt Register */
42
#define MII_DM9161_INTR 0x15
43
#define MII_DM9161_INTR_PEND            0x8000
44
#define MII_DM9161_INTR_DPLX_MASK       0x0800
45
#define MII_DM9161_INTR_SPD_MASK        0x0400
46
#define MII_DM9161_INTR_LINK_MASK       0x0200
47
#define MII_DM9161_INTR_MASK            0x0100
48
#define MII_DM9161_INTR_DPLX_CHANGE     0x0010
49
#define MII_DM9161_INTR_SPD_CHANGE      0x0008
50
#define MII_DM9161_INTR_LINK_CHANGE     0x0004
51
#define MII_DM9161_INTR_INIT            0x0000
52
#define MII_DM9161_INTR_STOP    \
53
(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
54
 | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
55
 
56
/* DM9161 10BT Configuration/Status */
57
#define MII_DM9161_10BTCSR      0x12
58
#define MII_DM9161_10BTCSR_INIT 0x7800
59
 
60
MODULE_DESCRIPTION("Davicom PHY driver");
61
MODULE_AUTHOR("Andy Fleming");
62
MODULE_LICENSE("GPL");
63
 
64
 
65
#define DM9161_DELAY 1
66
static int dm9161_config_intr(struct phy_device *phydev)
67
{
68
        int temp;
69
 
70
        temp = phy_read(phydev, MII_DM9161_INTR);
71
 
72
        if (temp < 0)
73
                return temp;
74
 
75
        if(PHY_INTERRUPT_ENABLED == phydev->interrupts )
76
                temp &= ~(MII_DM9161_INTR_STOP);
77
        else
78
                temp |= MII_DM9161_INTR_STOP;
79
 
80
        temp = phy_write(phydev, MII_DM9161_INTR, temp);
81
 
82
        return temp;
83
}
84
 
85
static int dm9161_config_aneg(struct phy_device *phydev)
86
{
87
        int err;
88
 
89
        /* Isolate the PHY */
90
        err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE);
91
 
92
        if (err < 0)
93
                return err;
94
 
95
        /* Configure the new settings */
96
        err = genphy_config_aneg(phydev);
97
 
98
        if (err < 0)
99
                return err;
100
 
101
        return 0;
102
}
103
 
104
static int dm9161_config_init(struct phy_device *phydev)
105
{
106
        int err;
107
 
108
        /* Isolate the PHY */
109
        err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE);
110
 
111
        if (err < 0)
112
                return err;
113
 
114
        /* Do not bypass the scrambler/descrambler */
115
        err = phy_write(phydev, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
116
 
117
        if (err < 0)
118
                return err;
119
 
120
        /* Clear 10BTCSR to default */
121
        err = phy_write(phydev, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT);
122
 
123
        if (err < 0)
124
                return err;
125
 
126
        /* Reconnect the PHY, and enable Autonegotiation */
127
        err = phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
128
 
129
        if (err < 0)
130
                return err;
131
 
132
        return 0;
133
}
134
 
135
static int dm9161_ack_interrupt(struct phy_device *phydev)
136
{
137
        int err = phy_read(phydev, MII_DM9161_INTR);
138
 
139
        return (err < 0) ? err : 0;
140
}
141
 
142
static struct phy_driver dm9161e_driver = {
143
        .phy_id         = 0x0181b880,
144
        .name           = "Davicom DM9161E",
145
        .phy_id_mask    = 0x0ffffff0,
146
        .features       = PHY_BASIC_FEATURES,
147
        .config_init    = dm9161_config_init,
148
        .config_aneg    = dm9161_config_aneg,
149
        .read_status    = genphy_read_status,
150
        .driver         = { .owner = THIS_MODULE,},
151
};
152
 
153
static struct phy_driver dm9161a_driver = {
154
        .phy_id         = 0x0181b8a0,
155
        .name           = "Davicom DM9161A",
156
        .phy_id_mask    = 0x0ffffff0,
157
        .features       = PHY_BASIC_FEATURES,
158
        .config_init    = dm9161_config_init,
159
        .config_aneg    = dm9161_config_aneg,
160
        .read_status    = genphy_read_status,
161
        .driver         = { .owner = THIS_MODULE,},
162
};
163
 
164
static struct phy_driver dm9131_driver = {
165
        .phy_id         = 0x00181b80,
166
        .name           = "Davicom DM9131",
167
        .phy_id_mask    = 0x0ffffff0,
168
        .features       = PHY_BASIC_FEATURES,
169
        .flags          = PHY_HAS_INTERRUPT,
170
        .config_aneg    = genphy_config_aneg,
171
        .read_status    = genphy_read_status,
172
        .ack_interrupt  = dm9161_ack_interrupt,
173
        .config_intr    = dm9161_config_intr,
174
        .driver         = { .owner = THIS_MODULE,},
175
};
176
 
177
static int __init davicom_init(void)
178
{
179
        int ret;
180
 
181
        ret = phy_driver_register(&dm9161e_driver);
182
        if (ret)
183
                goto err1;
184
 
185
        ret = phy_driver_register(&dm9161a_driver);
186
        if (ret)
187
                goto err2;
188
 
189
        ret = phy_driver_register(&dm9131_driver);
190
        if (ret)
191
                goto err3;
192
        return 0;
193
 
194
 err3:
195
        phy_driver_unregister(&dm9161a_driver);
196
 err2:
197
        phy_driver_unregister(&dm9161e_driver);
198
 err1:
199
        return ret;
200
}
201
 
202
static void __exit davicom_exit(void)
203
{
204
        phy_driver_unregister(&dm9161e_driver);
205
        phy_driver_unregister(&dm9161a_driver);
206
        phy_driver_unregister(&dm9131_driver);
207
}
208
 
209
module_init(davicom_init);
210
module_exit(davicom_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.