davicom.c revision 8b7c1664405a1262bb78e80011ec10aa6b79df81
100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming/*
200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming * drivers/net/phy/davicom.c
300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming *
400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming * Driver for Davicom PHYs
500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming *
600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming * Author: Andy Fleming
700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming *
800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming * Copyright (c) 2004 Freescale Semiconductor, Inc.
900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming *
1000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming * This program is free software; you can redistribute  it and/or modify it
1100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming * under  the terms of  the GNU General  Public License as published by the
1200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming * Free Software Foundation;  either version 2 of the  License, or (at your
1300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming * option) any later version.
1400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming *
1500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming */
1600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/kernel.h>
1700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/string.h>
1800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/errno.h>
1900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/unistd.h>
2000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/slab.h>
2100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/interrupt.h>
2200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/init.h>
2300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/delay.h>
2400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/netdevice.h>
2500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/etherdevice.h>
2600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/skbuff.h>
2700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/spinlock.h>
2800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/mm.h>
2900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/module.h>
3000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/mii.h>
3100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/ethtool.h>
3200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <linux/phy.h>
3300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
3400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <asm/io.h>
3500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <asm/irq.h>
3600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#include <asm/uaccess.h>
3700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
3800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_SCR		0x10
3900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_SCR_INIT	0x0610
408b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo#define MII_DM9161_SCR_RMII	0x0100
4100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
4200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming/* DM9161 Interrupt Register */
4300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR	0x15
4400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_PEND		0x8000
4500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_DPLX_MASK	0x0800
4600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_SPD_MASK	0x0400
4700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_LINK_MASK	0x0200
4800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_MASK		0x0100
4900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_DPLX_CHANGE	0x0010
5000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_SPD_CHANGE	0x0008
5100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_LINK_CHANGE	0x0004
5200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_INIT 		0x0000
5300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_INTR_STOP	\
5400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
5500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
5600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
5700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming/* DM9161 10BT Configuration/Status */
5800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_10BTCSR	0x12
5900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define MII_DM9161_10BTCSR_INIT	0x7800
6000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
6100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy FlemingMODULE_DESCRIPTION("Davicom PHY driver");
6200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy FlemingMODULE_AUTHOR("Andy Fleming");
6300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy FlemingMODULE_LICENSE("GPL");
6400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
6500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
6600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming#define DM9161_DELAY 1
6700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingstatic int dm9161_config_intr(struct phy_device *phydev)
6800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming{
6900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	int temp;
7000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
7100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	temp = phy_read(phydev, MII_DM9161_INTR);
7200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
7300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (temp < 0)
7400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		return temp;
7500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
7600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if(PHY_INTERRUPT_ENABLED == phydev->interrupts )
7700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		temp &= ~(MII_DM9161_INTR_STOP);
7800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	else
7900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		temp |= MII_DM9161_INTR_STOP;
8000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
8100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	temp = phy_write(phydev, MII_DM9161_INTR, temp);
8200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
8300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	return temp;
8400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming}
8500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
8600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingstatic int dm9161_config_aneg(struct phy_device *phydev)
8700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming{
8800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	int err;
8900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
9000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	/* Isolate the PHY */
9100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE);
9200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
9300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (err < 0)
9400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		return err;
9500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
9600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	/* Configure the new settings */
9700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	err = genphy_config_aneg(phydev);
9800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
9900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (err < 0)
10000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		return err;
10100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
10200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	return 0;
10300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming}
10400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
10500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingstatic int dm9161_config_init(struct phy_device *phydev)
10600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming{
1078b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo	int err, temp;
10800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
10900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	/* Isolate the PHY */
11000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE);
11100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
11200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (err < 0)
11300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		return err;
11400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
1158b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo	switch (phydev->interface) {
1168b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo	case PHY_INTERFACE_MODE_MII:
1178b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo		temp = MII_DM9161_SCR_INIT;
1188b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo		break;
1198b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo	case PHY_INTERFACE_MODE_RMII:
1208b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo		temp =  MII_DM9161_SCR_INIT | MII_DM9161_SCR_RMII;
1218b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo		break;
1228b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo	default:
1238b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo		return -EINVAL;
1248b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo	}
12500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
1268b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo	/* Do not bypass the scrambler/descrambler */
1278b7c1664405a1262bb78e80011ec10aa6b79df81frederic Rodo	err = phy_write(phydev, MII_DM9161_SCR, temp);
12800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (err < 0)
12900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		return err;
13000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
13100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	/* Clear 10BTCSR to default */
13200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	err = phy_write(phydev, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT);
13300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
13400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (err < 0)
13500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		return err;
13600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
13700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	/* Reconnect the PHY, and enable Autonegotiation */
13800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	err = phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
13900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
14000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (err < 0)
14100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		return err;
14200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
14300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	return 0;
14400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming}
14500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
14600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingstatic int dm9161_ack_interrupt(struct phy_device *phydev)
14700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming{
14800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	int err = phy_read(phydev, MII_DM9161_INTR);
14900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
15000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	return (err < 0) ? err : 0;
15100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming}
15200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
15312414db11da8789d9a6b549c4899250f6e116630Kim Phillipsstatic struct phy_driver dm9161e_driver = {
15400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.phy_id		= 0x0181b880,
15500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.name		= "Davicom DM9161E",
15600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.phy_id_mask	= 0x0ffffff0,
15700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.features	= PHY_BASIC_FEATURES,
15800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.config_init	= dm9161_config_init,
15900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.config_aneg	= dm9161_config_aneg,
16000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.read_status	= genphy_read_status,
16112414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.driver		= { .owner = THIS_MODULE,},
16212414db11da8789d9a6b549c4899250f6e116630Kim Phillips};
16312414db11da8789d9a6b549c4899250f6e116630Kim Phillips
16412414db11da8789d9a6b549c4899250f6e116630Kim Phillipsstatic struct phy_driver dm9161a_driver = {
16512414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.phy_id		= 0x0181b8a0,
16612414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.name		= "Davicom DM9161A",
16712414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.phy_id_mask	= 0x0ffffff0,
16812414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.features	= PHY_BASIC_FEATURES,
16912414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.config_init	= dm9161_config_init,
17012414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.config_aneg	= dm9161_config_aneg,
17112414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.read_status	= genphy_read_status,
17212414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.driver		= { .owner = THIS_MODULE,},
17300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming};
17400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
17500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingstatic struct phy_driver dm9131_driver = {
17600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.phy_id		= 0x00181b80,
17700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.name		= "Davicom DM9131",
17800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.phy_id_mask	= 0x0ffffff0,
17900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.features	= PHY_BASIC_FEATURES,
18000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.flags		= PHY_HAS_INTERRUPT,
18100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.config_aneg	= genphy_config_aneg,
18200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.read_status	= genphy_read_status,
18300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.ack_interrupt	= dm9161_ack_interrupt,
18400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	.config_intr	= dm9161_config_intr,
18512414db11da8789d9a6b549c4899250f6e116630Kim Phillips	.driver		= { .owner = THIS_MODULE,},
18600db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming};
18700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
18800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingstatic int __init davicom_init(void)
18900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming{
19000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	int ret;
19100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
19212414db11da8789d9a6b549c4899250f6e116630Kim Phillips	ret = phy_driver_register(&dm9161e_driver);
19300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (ret)
19400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		goto err1;
19500db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
19612414db11da8789d9a6b549c4899250f6e116630Kim Phillips	ret = phy_driver_register(&dm9161a_driver);
19700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	if (ret)
19800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming		goto err2;
19912414db11da8789d9a6b549c4899250f6e116630Kim Phillips
20012414db11da8789d9a6b549c4899250f6e116630Kim Phillips	ret = phy_driver_register(&dm9131_driver);
20112414db11da8789d9a6b549c4899250f6e116630Kim Phillips	if (ret)
20212414db11da8789d9a6b549c4899250f6e116630Kim Phillips		goto err3;
20300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	return 0;
20400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
20512414db11da8789d9a6b549c4899250f6e116630Kim Phillips err3:
20612414db11da8789d9a6b549c4899250f6e116630Kim Phillips	phy_driver_unregister(&dm9161a_driver);
20712414db11da8789d9a6b549c4899250f6e116630Kim Phillips err2:
20812414db11da8789d9a6b549c4899250f6e116630Kim Phillips	phy_driver_unregister(&dm9161e_driver);
20900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming err1:
21000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	return ret;
21100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming}
21200db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
21300db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingstatic void __exit davicom_exit(void)
21400db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming{
21512414db11da8789d9a6b549c4899250f6e116630Kim Phillips	phy_driver_unregister(&dm9161e_driver);
21612414db11da8789d9a6b549c4899250f6e116630Kim Phillips	phy_driver_unregister(&dm9161a_driver);
21700db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming	phy_driver_unregister(&dm9131_driver);
21800db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming}
21900db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Fleming
22000db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingmodule_init(davicom_init);
22100db8189d984d6c51226dafbbe4a667ce9b7d5daAndy Flemingmodule_exit(davicom_exit);
222