ASoC: wm8904: add new compatible string
[cascardo/linux.git] / drivers / net / phy / micrel.c
1 /*
2  * drivers/net/phy/micrel.c
3  *
4  * Driver for Micrel PHYs
5  *
6  * Author: David J. Choi
7  *
8  * Copyright (c) 2010-2013 Micrel, Inc.
9  * Copyright (c) 2014 Johan Hovold <johan@kernel.org>
10  *
11  * This program is free software; you can redistribute  it and/or modify it
12  * under  the terms of  the GNU General  Public License as published by the
13  * Free Software Foundation;  either version 2 of the  License, or (at your
14  * option) any later version.
15  *
16  * Support : Micrel Phys:
17  *              Giga phys: ksz9021, ksz9031
18  *              100/10 Phys : ksz8001, ksz8721, ksz8737, ksz8041
19  *                         ksz8021, ksz8031, ksz8051,
20  *                         ksz8081, ksz8091,
21  *                         ksz8061,
22  *              Switch : ksz8873, ksz886x
23  */
24
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/phy.h>
28 #include <linux/micrel_phy.h>
29 #include <linux/of.h>
30 #include <linux/clk.h>
31
32 /* Operation Mode Strap Override */
33 #define MII_KSZPHY_OMSO                         0x16
34 #define KSZPHY_OMSO_B_CAST_OFF                  BIT(9)
35 #define KSZPHY_OMSO_RMII_OVERRIDE               BIT(1)
36 #define KSZPHY_OMSO_MII_OVERRIDE                BIT(0)
37
38 /* general Interrupt control/status reg in vendor specific block. */
39 #define MII_KSZPHY_INTCS                        0x1B
40 #define KSZPHY_INTCS_JABBER                     BIT(15)
41 #define KSZPHY_INTCS_RECEIVE_ERR                BIT(14)
42 #define KSZPHY_INTCS_PAGE_RECEIVE               BIT(13)
43 #define KSZPHY_INTCS_PARELLEL                   BIT(12)
44 #define KSZPHY_INTCS_LINK_PARTNER_ACK           BIT(11)
45 #define KSZPHY_INTCS_LINK_DOWN                  BIT(10)
46 #define KSZPHY_INTCS_REMOTE_FAULT               BIT(9)
47 #define KSZPHY_INTCS_LINK_UP                    BIT(8)
48 #define KSZPHY_INTCS_ALL                        (KSZPHY_INTCS_LINK_UP |\
49                                                 KSZPHY_INTCS_LINK_DOWN)
50
51 /* PHY Control 1 */
52 #define MII_KSZPHY_CTRL_1                       0x1e
53
54 /* PHY Control 2 / PHY Control (if no PHY Control 1) */
55 #define MII_KSZPHY_CTRL_2                       0x1f
56 #define MII_KSZPHY_CTRL                         MII_KSZPHY_CTRL_2
57 /* bitmap of PHY register to set interrupt mode */
58 #define KSZPHY_CTRL_INT_ACTIVE_HIGH             BIT(9)
59 #define KSZPHY_RMII_REF_CLK_SEL                 BIT(7)
60
61 /* Write/read to/from extended registers */
62 #define MII_KSZPHY_EXTREG                       0x0b
63 #define KSZPHY_EXTREG_WRITE                     0x8000
64
65 #define MII_KSZPHY_EXTREG_WRITE                 0x0c
66 #define MII_KSZPHY_EXTREG_READ                  0x0d
67
68 /* Extended registers */
69 #define MII_KSZPHY_CLK_CONTROL_PAD_SKEW         0x104
70 #define MII_KSZPHY_RX_DATA_PAD_SKEW             0x105
71 #define MII_KSZPHY_TX_DATA_PAD_SKEW             0x106
72
73 #define PS_TO_REG                               200
74
75 struct kszphy_type {
76         u32 led_mode_reg;
77         u16 interrupt_level_mask;
78         bool has_broadcast_disable;
79         bool has_rmii_ref_clk_sel;
80 };
81
82 struct kszphy_priv {
83         const struct kszphy_type *type;
84         int led_mode;
85         bool rmii_ref_clk_sel;
86         bool rmii_ref_clk_sel_val;
87 };
88
89 static const struct kszphy_type ksz8021_type = {
90         .led_mode_reg           = MII_KSZPHY_CTRL_2,
91         .has_rmii_ref_clk_sel   = true,
92 };
93
94 static const struct kszphy_type ksz8041_type = {
95         .led_mode_reg           = MII_KSZPHY_CTRL_1,
96 };
97
98 static const struct kszphy_type ksz8051_type = {
99         .led_mode_reg           = MII_KSZPHY_CTRL_2,
100 };
101
102 static const struct kszphy_type ksz8081_type = {
103         .led_mode_reg           = MII_KSZPHY_CTRL_2,
104         .has_broadcast_disable  = true,
105         .has_rmii_ref_clk_sel   = true,
106 };
107
108 static const struct kszphy_type ks8737_type = {
109         .interrupt_level_mask   = BIT(14),
110 };
111
112 static const struct kszphy_type ksz9021_type = {
113         .interrupt_level_mask   = BIT(14),
114 };
115
116 static int kszphy_extended_write(struct phy_device *phydev,
117                                 u32 regnum, u16 val)
118 {
119         phy_write(phydev, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | regnum);
120         return phy_write(phydev, MII_KSZPHY_EXTREG_WRITE, val);
121 }
122
123 static int kszphy_extended_read(struct phy_device *phydev,
124                                 u32 regnum)
125 {
126         phy_write(phydev, MII_KSZPHY_EXTREG, regnum);
127         return phy_read(phydev, MII_KSZPHY_EXTREG_READ);
128 }
129
130 static int kszphy_ack_interrupt(struct phy_device *phydev)
131 {
132         /* bit[7..0] int status, which is a read and clear register. */
133         int rc;
134
135         rc = phy_read(phydev, MII_KSZPHY_INTCS);
136
137         return (rc < 0) ? rc : 0;
138 }
139
140 static int kszphy_config_intr(struct phy_device *phydev)
141 {
142         const struct kszphy_type *type = phydev->drv->driver_data;
143         int temp;
144         u16 mask;
145
146         if (type && type->interrupt_level_mask)
147                 mask = type->interrupt_level_mask;
148         else
149                 mask = KSZPHY_CTRL_INT_ACTIVE_HIGH;
150
151         /* set the interrupt pin active low */
152         temp = phy_read(phydev, MII_KSZPHY_CTRL);
153         if (temp < 0)
154                 return temp;
155         temp &= ~mask;
156         phy_write(phydev, MII_KSZPHY_CTRL, temp);
157
158         /* enable / disable interrupts */
159         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
160                 temp = KSZPHY_INTCS_ALL;
161         else
162                 temp = 0;
163
164         return phy_write(phydev, MII_KSZPHY_INTCS, temp);
165 }
166
167 static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val)
168 {
169         int ctrl;
170
171         ctrl = phy_read(phydev, MII_KSZPHY_CTRL);
172         if (ctrl < 0)
173                 return ctrl;
174
175         if (val)
176                 ctrl |= KSZPHY_RMII_REF_CLK_SEL;
177         else
178                 ctrl &= ~KSZPHY_RMII_REF_CLK_SEL;
179
180         return phy_write(phydev, MII_KSZPHY_CTRL, ctrl);
181 }
182
183 static int kszphy_setup_led(struct phy_device *phydev, u32 reg, int val)
184 {
185         int rc, temp, shift;
186
187         switch (reg) {
188         case MII_KSZPHY_CTRL_1:
189                 shift = 14;
190                 break;
191         case MII_KSZPHY_CTRL_2:
192                 shift = 4;
193                 break;
194         default:
195                 return -EINVAL;
196         }
197
198         temp = phy_read(phydev, reg);
199         if (temp < 0) {
200                 rc = temp;
201                 goto out;
202         }
203
204         temp &= ~(3 << shift);
205         temp |= val << shift;
206         rc = phy_write(phydev, reg, temp);
207 out:
208         if (rc < 0)
209                 dev_err(&phydev->dev, "failed to set led mode\n");
210
211         return rc;
212 }
213
214 /* Disable PHY address 0 as the broadcast address, so that it can be used as a
215  * unique (non-broadcast) address on a shared bus.
216  */
217 static int kszphy_broadcast_disable(struct phy_device *phydev)
218 {
219         int ret;
220
221         ret = phy_read(phydev, MII_KSZPHY_OMSO);
222         if (ret < 0)
223                 goto out;
224
225         ret = phy_write(phydev, MII_KSZPHY_OMSO, ret | KSZPHY_OMSO_B_CAST_OFF);
226 out:
227         if (ret)
228                 dev_err(&phydev->dev, "failed to disable broadcast address\n");
229
230         return ret;
231 }
232
233 static int kszphy_config_init(struct phy_device *phydev)
234 {
235         struct kszphy_priv *priv = phydev->priv;
236         const struct kszphy_type *type;
237         int ret;
238
239         if (!priv)
240                 return 0;
241
242         type = priv->type;
243
244         if (type->has_broadcast_disable)
245                 kszphy_broadcast_disable(phydev);
246
247         if (priv->rmii_ref_clk_sel) {
248                 ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
249                 if (ret) {
250                         dev_err(&phydev->dev, "failed to set rmii reference clock\n");
251                         return ret;
252                 }
253         }
254
255         if (priv->led_mode >= 0)
256                 kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
257
258         return 0;
259 }
260
261 static int ksz8021_config_init(struct phy_device *phydev)
262 {
263         int rc;
264
265         rc = kszphy_config_init(phydev);
266         if (rc)
267                 return rc;
268
269         rc = kszphy_broadcast_disable(phydev);
270
271         return rc < 0 ? rc : 0;
272 }
273
274 static int ksz9021_load_values_from_of(struct phy_device *phydev,
275                                        struct device_node *of_node, u16 reg,
276                                        char *field1, char *field2,
277                                        char *field3, char *field4)
278 {
279         int val1 = -1;
280         int val2 = -2;
281         int val3 = -3;
282         int val4 = -4;
283         int newval;
284         int matches = 0;
285
286         if (!of_property_read_u32(of_node, field1, &val1))
287                 matches++;
288
289         if (!of_property_read_u32(of_node, field2, &val2))
290                 matches++;
291
292         if (!of_property_read_u32(of_node, field3, &val3))
293                 matches++;
294
295         if (!of_property_read_u32(of_node, field4, &val4))
296                 matches++;
297
298         if (!matches)
299                 return 0;
300
301         if (matches < 4)
302                 newval = kszphy_extended_read(phydev, reg);
303         else
304                 newval = 0;
305
306         if (val1 != -1)
307                 newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0);
308
309         if (val2 != -2)
310                 newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4);
311
312         if (val3 != -3)
313                 newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8);
314
315         if (val4 != -4)
316                 newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12);
317
318         return kszphy_extended_write(phydev, reg, newval);
319 }
320
321 static int ksz9021_config_init(struct phy_device *phydev)
322 {
323         struct device *dev = &phydev->dev;
324         struct device_node *of_node = dev->of_node;
325
326         if (!of_node && dev->parent->of_node)
327                 of_node = dev->parent->of_node;
328
329         if (of_node) {
330                 ksz9021_load_values_from_of(phydev, of_node,
331                                     MII_KSZPHY_CLK_CONTROL_PAD_SKEW,
332                                     "txen-skew-ps", "txc-skew-ps",
333                                     "rxdv-skew-ps", "rxc-skew-ps");
334                 ksz9021_load_values_from_of(phydev, of_node,
335                                     MII_KSZPHY_RX_DATA_PAD_SKEW,
336                                     "rxd0-skew-ps", "rxd1-skew-ps",
337                                     "rxd2-skew-ps", "rxd3-skew-ps");
338                 ksz9021_load_values_from_of(phydev, of_node,
339                                     MII_KSZPHY_TX_DATA_PAD_SKEW,
340                                     "txd0-skew-ps", "txd1-skew-ps",
341                                     "txd2-skew-ps", "txd3-skew-ps");
342         }
343         return 0;
344 }
345
346 #define MII_KSZ9031RN_MMD_CTRL_REG      0x0d
347 #define MII_KSZ9031RN_MMD_REGDATA_REG   0x0e
348 #define OP_DATA                         1
349 #define KSZ9031_PS_TO_REG               60
350
351 /* Extended registers */
352 #define MII_KSZ9031RN_CONTROL_PAD_SKEW  4
353 #define MII_KSZ9031RN_RX_DATA_PAD_SKEW  5
354 #define MII_KSZ9031RN_TX_DATA_PAD_SKEW  6
355 #define MII_KSZ9031RN_CLK_PAD_SKEW      8
356
357 static int ksz9031_extended_write(struct phy_device *phydev,
358                                   u8 mode, u32 dev_addr, u32 regnum, u16 val)
359 {
360         phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr);
361         phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum);
362         phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
363         return phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, val);
364 }
365
366 static int ksz9031_extended_read(struct phy_device *phydev,
367                                  u8 mode, u32 dev_addr, u32 regnum)
368 {
369         phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr);
370         phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum);
371         phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
372         return phy_read(phydev, MII_KSZ9031RN_MMD_REGDATA_REG);
373 }
374
375 static int ksz9031_of_load_skew_values(struct phy_device *phydev,
376                                        struct device_node *of_node,
377                                        u16 reg, size_t field_sz,
378                                        char *field[], u8 numfields)
379 {
380         int val[4] = {-1, -2, -3, -4};
381         int matches = 0;
382         u16 mask;
383         u16 maxval;
384         u16 newval;
385         int i;
386
387         for (i = 0; i < numfields; i++)
388                 if (!of_property_read_u32(of_node, field[i], val + i))
389                         matches++;
390
391         if (!matches)
392                 return 0;
393
394         if (matches < numfields)
395                 newval = ksz9031_extended_read(phydev, OP_DATA, 2, reg);
396         else
397                 newval = 0;
398
399         maxval = (field_sz == 4) ? 0xf : 0x1f;
400         for (i = 0; i < numfields; i++)
401                 if (val[i] != -(i + 1)) {
402                         mask = 0xffff;
403                         mask ^= maxval << (field_sz * i);
404                         newval = (newval & mask) |
405                                 (((val[i] / KSZ9031_PS_TO_REG) & maxval)
406                                         << (field_sz * i));
407                 }
408
409         return ksz9031_extended_write(phydev, OP_DATA, 2, reg, newval);
410 }
411
412 static int ksz9031_config_init(struct phy_device *phydev)
413 {
414         struct device *dev = &phydev->dev;
415         struct device_node *of_node = dev->of_node;
416         char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"};
417         char *rx_data_skews[4] = {
418                 "rxd0-skew-ps", "rxd1-skew-ps",
419                 "rxd2-skew-ps", "rxd3-skew-ps"
420         };
421         char *tx_data_skews[4] = {
422                 "txd0-skew-ps", "txd1-skew-ps",
423                 "txd2-skew-ps", "txd3-skew-ps"
424         };
425         char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"};
426
427         if (!of_node && dev->parent->of_node)
428                 of_node = dev->parent->of_node;
429
430         if (of_node) {
431                 ksz9031_of_load_skew_values(phydev, of_node,
432                                 MII_KSZ9031RN_CLK_PAD_SKEW, 5,
433                                 clk_skews, 2);
434
435                 ksz9031_of_load_skew_values(phydev, of_node,
436                                 MII_KSZ9031RN_CONTROL_PAD_SKEW, 4,
437                                 control_skews, 2);
438
439                 ksz9031_of_load_skew_values(phydev, of_node,
440                                 MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4,
441                                 rx_data_skews, 4);
442
443                 ksz9031_of_load_skew_values(phydev, of_node,
444                                 MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4,
445                                 tx_data_skews, 4);
446         }
447         return 0;
448 }
449
450 #define KSZ8873MLL_GLOBAL_CONTROL_4     0x06
451 #define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX      BIT(6)
452 #define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED       BIT(4)
453 static int ksz8873mll_read_status(struct phy_device *phydev)
454 {
455         int regval;
456
457         /* dummy read */
458         regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4);
459
460         regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4);
461
462         if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX)
463                 phydev->duplex = DUPLEX_HALF;
464         else
465                 phydev->duplex = DUPLEX_FULL;
466
467         if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_SPEED)
468                 phydev->speed = SPEED_10;
469         else
470                 phydev->speed = SPEED_100;
471
472         phydev->link = 1;
473         phydev->pause = phydev->asym_pause = 0;
474
475         return 0;
476 }
477
478 static int ksz8873mll_config_aneg(struct phy_device *phydev)
479 {
480         return 0;
481 }
482
483 /* This routine returns -1 as an indication to the caller that the
484  * Micrel ksz9021 10/100/1000 PHY does not support standard IEEE
485  * MMD extended PHY registers.
486  */
487 static int
488 ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
489                       int regnum)
490 {
491         return -1;
492 }
493
494 /* This routine does nothing since the Micrel ksz9021 does not support
495  * standard IEEE MMD extended PHY registers.
496  */
497 static void
498 ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
499                       int regnum, u32 val)
500 {
501 }
502
503 static int kszphy_probe(struct phy_device *phydev)
504 {
505         const struct kszphy_type *type = phydev->drv->driver_data;
506         struct device_node *np = phydev->dev.of_node;
507         struct kszphy_priv *priv;
508         struct clk *clk;
509         int ret;
510
511         priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL);
512         if (!priv)
513                 return -ENOMEM;
514
515         phydev->priv = priv;
516
517         priv->type = type;
518
519         if (type->led_mode_reg) {
520                 ret = of_property_read_u32(np, "micrel,led-mode",
521                                 &priv->led_mode);
522                 if (ret)
523                         priv->led_mode = -1;
524
525                 if (priv->led_mode > 3) {
526                         dev_err(&phydev->dev, "invalid led mode: 0x%02x\n",
527                                         priv->led_mode);
528                         priv->led_mode = -1;
529                 }
530         } else {
531                 priv->led_mode = -1;
532         }
533
534         clk = devm_clk_get(&phydev->dev, "rmii-ref");
535         if (!IS_ERR(clk)) {
536                 unsigned long rate = clk_get_rate(clk);
537                 bool rmii_ref_clk_sel_25_mhz;
538
539                 priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel;
540                 rmii_ref_clk_sel_25_mhz = of_property_read_bool(np,
541                                 "micrel,rmii-reference-clock-select-25-mhz");
542
543                 if (rate > 24500000 && rate < 25500000) {
544                         priv->rmii_ref_clk_sel_val = rmii_ref_clk_sel_25_mhz;
545                 } else if (rate > 49500000 && rate < 50500000) {
546                         priv->rmii_ref_clk_sel_val = !rmii_ref_clk_sel_25_mhz;
547                 } else {
548                         dev_err(&phydev->dev, "Clock rate out of range: %ld\n", rate);
549                         return -EINVAL;
550                 }
551         }
552
553         /* Support legacy board-file configuration */
554         if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) {
555                 priv->rmii_ref_clk_sel = true;
556                 priv->rmii_ref_clk_sel_val = true;
557         }
558
559         return 0;
560 }
561
562 static struct phy_driver ksphy_driver[] = {
563 {
564         .phy_id         = PHY_ID_KS8737,
565         .phy_id_mask    = 0x00fffff0,
566         .name           = "Micrel KS8737",
567         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
568         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
569         .driver_data    = &ks8737_type,
570         .config_init    = kszphy_config_init,
571         .config_aneg    = genphy_config_aneg,
572         .read_status    = genphy_read_status,
573         .ack_interrupt  = kszphy_ack_interrupt,
574         .config_intr    = kszphy_config_intr,
575         .suspend        = genphy_suspend,
576         .resume         = genphy_resume,
577         .driver         = { .owner = THIS_MODULE,},
578 }, {
579         .phy_id         = PHY_ID_KSZ8021,
580         .phy_id_mask    = 0x00ffffff,
581         .name           = "Micrel KSZ8021 or KSZ8031",
582         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
583                            SUPPORTED_Asym_Pause),
584         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
585         .driver_data    = &ksz8021_type,
586         .probe          = kszphy_probe,
587         .config_init    = ksz8021_config_init,
588         .config_aneg    = genphy_config_aneg,
589         .read_status    = genphy_read_status,
590         .ack_interrupt  = kszphy_ack_interrupt,
591         .config_intr    = kszphy_config_intr,
592         .suspend        = genphy_suspend,
593         .resume         = genphy_resume,
594         .driver         = { .owner = THIS_MODULE,},
595 }, {
596         .phy_id         = PHY_ID_KSZ8031,
597         .phy_id_mask    = 0x00ffffff,
598         .name           = "Micrel KSZ8031",
599         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
600                            SUPPORTED_Asym_Pause),
601         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
602         .driver_data    = &ksz8021_type,
603         .probe          = kszphy_probe,
604         .config_init    = ksz8021_config_init,
605         .config_aneg    = genphy_config_aneg,
606         .read_status    = genphy_read_status,
607         .ack_interrupt  = kszphy_ack_interrupt,
608         .config_intr    = kszphy_config_intr,
609         .suspend        = genphy_suspend,
610         .resume         = genphy_resume,
611         .driver         = { .owner = THIS_MODULE,},
612 }, {
613         .phy_id         = PHY_ID_KSZ8041,
614         .phy_id_mask    = 0x00fffff0,
615         .name           = "Micrel KSZ8041",
616         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
617                                 | SUPPORTED_Asym_Pause),
618         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
619         .driver_data    = &ksz8041_type,
620         .probe          = kszphy_probe,
621         .config_init    = kszphy_config_init,
622         .config_aneg    = genphy_config_aneg,
623         .read_status    = genphy_read_status,
624         .ack_interrupt  = kszphy_ack_interrupt,
625         .config_intr    = kszphy_config_intr,
626         .suspend        = genphy_suspend,
627         .resume         = genphy_resume,
628         .driver         = { .owner = THIS_MODULE,},
629 }, {
630         .phy_id         = PHY_ID_KSZ8041RNLI,
631         .phy_id_mask    = 0x00fffff0,
632         .name           = "Micrel KSZ8041RNLI",
633         .features       = PHY_BASIC_FEATURES |
634                           SUPPORTED_Pause | SUPPORTED_Asym_Pause,
635         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
636         .driver_data    = &ksz8041_type,
637         .probe          = kszphy_probe,
638         .config_init    = kszphy_config_init,
639         .config_aneg    = genphy_config_aneg,
640         .read_status    = genphy_read_status,
641         .ack_interrupt  = kszphy_ack_interrupt,
642         .config_intr    = kszphy_config_intr,
643         .suspend        = genphy_suspend,
644         .resume         = genphy_resume,
645         .driver         = { .owner = THIS_MODULE,},
646 }, {
647         .phy_id         = PHY_ID_KSZ8051,
648         .phy_id_mask    = 0x00fffff0,
649         .name           = "Micrel KSZ8051",
650         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
651                                 | SUPPORTED_Asym_Pause),
652         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
653         .driver_data    = &ksz8051_type,
654         .probe          = kszphy_probe,
655         .config_init    = kszphy_config_init,
656         .config_aneg    = genphy_config_aneg,
657         .read_status    = genphy_read_status,
658         .ack_interrupt  = kszphy_ack_interrupt,
659         .config_intr    = kszphy_config_intr,
660         .suspend        = genphy_suspend,
661         .resume         = genphy_resume,
662         .driver         = { .owner = THIS_MODULE,},
663 }, {
664         .phy_id         = PHY_ID_KSZ8001,
665         .name           = "Micrel KSZ8001 or KS8721",
666         .phy_id_mask    = 0x00ffffff,
667         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
668         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
669         .driver_data    = &ksz8041_type,
670         .probe          = kszphy_probe,
671         .config_init    = kszphy_config_init,
672         .config_aneg    = genphy_config_aneg,
673         .read_status    = genphy_read_status,
674         .ack_interrupt  = kszphy_ack_interrupt,
675         .config_intr    = kszphy_config_intr,
676         .suspend        = genphy_suspend,
677         .resume         = genphy_resume,
678         .driver         = { .owner = THIS_MODULE,},
679 }, {
680         .phy_id         = PHY_ID_KSZ8081,
681         .name           = "Micrel KSZ8081 or KSZ8091",
682         .phy_id_mask    = 0x00fffff0,
683         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
684         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
685         .driver_data    = &ksz8081_type,
686         .probe          = kszphy_probe,
687         .config_init    = kszphy_config_init,
688         .config_aneg    = genphy_config_aneg,
689         .read_status    = genphy_read_status,
690         .ack_interrupt  = kszphy_ack_interrupt,
691         .config_intr    = kszphy_config_intr,
692         .suspend        = genphy_suspend,
693         .resume         = genphy_resume,
694         .driver         = { .owner = THIS_MODULE,},
695 }, {
696         .phy_id         = PHY_ID_KSZ8061,
697         .name           = "Micrel KSZ8061",
698         .phy_id_mask    = 0x00fffff0,
699         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
700         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
701         .config_init    = kszphy_config_init,
702         .config_aneg    = genphy_config_aneg,
703         .read_status    = genphy_read_status,
704         .ack_interrupt  = kszphy_ack_interrupt,
705         .config_intr    = kszphy_config_intr,
706         .suspend        = genphy_suspend,
707         .resume         = genphy_resume,
708         .driver         = { .owner = THIS_MODULE,},
709 }, {
710         .phy_id         = PHY_ID_KSZ9021,
711         .phy_id_mask    = 0x000ffffe,
712         .name           = "Micrel KSZ9021 Gigabit PHY",
713         .features       = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
714         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
715         .driver_data    = &ksz9021_type,
716         .config_init    = ksz9021_config_init,
717         .config_aneg    = genphy_config_aneg,
718         .read_status    = genphy_read_status,
719         .ack_interrupt  = kszphy_ack_interrupt,
720         .config_intr    = kszphy_config_intr,
721         .suspend        = genphy_suspend,
722         .resume         = genphy_resume,
723         .read_mmd_indirect = ksz9021_rd_mmd_phyreg,
724         .write_mmd_indirect = ksz9021_wr_mmd_phyreg,
725         .driver         = { .owner = THIS_MODULE, },
726 }, {
727         .phy_id         = PHY_ID_KSZ9031,
728         .phy_id_mask    = 0x00fffff0,
729         .name           = "Micrel KSZ9031 Gigabit PHY",
730         .features       = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
731         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
732         .driver_data    = &ksz9021_type,
733         .config_init    = ksz9031_config_init,
734         .config_aneg    = genphy_config_aneg,
735         .read_status    = genphy_read_status,
736         .ack_interrupt  = kszphy_ack_interrupt,
737         .config_intr    = kszphy_config_intr,
738         .suspend        = genphy_suspend,
739         .resume         = genphy_resume,
740         .driver         = { .owner = THIS_MODULE, },
741 }, {
742         .phy_id         = PHY_ID_KSZ8873MLL,
743         .phy_id_mask    = 0x00fffff0,
744         .name           = "Micrel KSZ8873MLL Switch",
745         .features       = (SUPPORTED_Pause | SUPPORTED_Asym_Pause),
746         .flags          = PHY_HAS_MAGICANEG,
747         .config_init    = kszphy_config_init,
748         .config_aneg    = ksz8873mll_config_aneg,
749         .read_status    = ksz8873mll_read_status,
750         .suspend        = genphy_suspend,
751         .resume         = genphy_resume,
752         .driver         = { .owner = THIS_MODULE, },
753 }, {
754         .phy_id         = PHY_ID_KSZ886X,
755         .phy_id_mask    = 0x00fffff0,
756         .name           = "Micrel KSZ886X Switch",
757         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
758         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
759         .config_init    = kszphy_config_init,
760         .config_aneg    = genphy_config_aneg,
761         .read_status    = genphy_read_status,
762         .suspend        = genphy_suspend,
763         .resume         = genphy_resume,
764         .driver         = { .owner = THIS_MODULE, },
765 } };
766
767 module_phy_driver(ksphy_driver);
768
769 MODULE_DESCRIPTION("Micrel PHY driver");
770 MODULE_AUTHOR("David J. Choi");
771 MODULE_LICENSE("GPL");
772
773 static struct mdio_device_id __maybe_unused micrel_tbl[] = {
774         { PHY_ID_KSZ9021, 0x000ffffe },
775         { PHY_ID_KSZ9031, 0x00fffff0 },
776         { PHY_ID_KSZ8001, 0x00ffffff },
777         { PHY_ID_KS8737, 0x00fffff0 },
778         { PHY_ID_KSZ8021, 0x00ffffff },
779         { PHY_ID_KSZ8031, 0x00ffffff },
780         { PHY_ID_KSZ8041, 0x00fffff0 },
781         { PHY_ID_KSZ8051, 0x00fffff0 },
782         { PHY_ID_KSZ8061, 0x00fffff0 },
783         { PHY_ID_KSZ8081, 0x00fffff0 },
784         { PHY_ID_KSZ8873MLL, 0x00fffff0 },
785         { PHY_ID_KSZ886X, 0x00fffff0 },
786         { }
787 };
788
789 MODULE_DEVICE_TABLE(mdio, micrel_tbl);