static void i2c_au1550_setup(struct i2c_au1550_data *priv) { volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; u32 stat; sp->psc_ctrl = PSC_CTRL_DISABLE; au_sync(); sp->psc_sel = PSC_SEL_PS_SMBUSMODE; sp->psc_smbcfg = 0; au_sync(); sp->psc_ctrl = PSC_CTRL_ENABLE; au_sync(); do { stat = sp->psc_smbstat; au_sync(); } while ((stat & PSC_SMBSTAT_SR) == 0); sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | PSC_SMBCFG_DD_DISABLE); sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); sp->psc_smbmsk = PSC_SMBMSK_ALLMASK; au_sync(); sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \ PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \ PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \ PSC_SMBTMR_SET_CH(15); au_sync(); sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE; do { stat = sp->psc_smbstat; au_sync(); } while ((stat & PSC_SMBSTAT_SR) == 0); sp->psc_ctrl = PSC_CTRL_SUSPEND; au_sync(); }
static void i2c_au1550_setup(struct i2c_au1550_data *priv) { unsigned long cfg; WR(priv, PSC_CTRL, PSC_CTRL_DISABLE); WR(priv, PSC_SEL, PSC_SEL_PS_SMBUSMODE); WR(priv, PSC_SMBCFG, 0); WR(priv, PSC_CTRL, PSC_CTRL_ENABLE); while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0) cpu_relax(); cfg = PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | PSC_SMBCFG_DD_DISABLE; WR(priv, PSC_SMBCFG, cfg); /* Divide by 8 to get a 6.25 MHz clock. The later protocol * timings are based on this clock. */ cfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); WR(priv, PSC_SMBCFG, cfg); WR(priv, PSC_SMBMSK, PSC_SMBMSK_ALLMASK); /* Set the protocol timer values. See Table 71 in the * Au1550 Data Book for standard timing values. */ WR(priv, PSC_SMBTMR, PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \ PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \ PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \ PSC_SMBTMR_SET_CH(15)); cfg |= PSC_SMBCFG_DE_ENABLE; WR(priv, PSC_SMBCFG, cfg); while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0) cpu_relax(); WR(priv, PSC_CTRL, PSC_CTRL_SUSPEND); }
/* * registering functions to load algorithms at runtime * Prior to calling us, the 50MHz clock frequency and routing * must have been set up for the PSC indicated by the adapter. */ static int __devinit i2c_au1550_probe(struct platform_device *pdev) { struct i2c_au1550_data *priv; volatile psc_smb_t *sp; struct resource *r; u32 stat; int ret; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { ret = -ENODEV; goto out; } priv = kzalloc(sizeof(struct i2c_au1550_data), GFP_KERNEL); if (!priv) { ret = -ENOMEM; goto out; } priv->ioarea = request_mem_region(r->start, r->end - r->start + 1, pdev->name); if (!priv->ioarea) { ret = -EBUSY; goto out_mem; } priv->psc_base = r->start; priv->xfer_timeout = 200; priv->ack_timeout = 200; priv->adap.id = I2C_HW_AU1550_PSC; priv->adap.nr = pdev->id; priv->adap.algo = &au1550_algo; priv->adap.algo_data = priv; priv->adap.dev.parent = &pdev->dev; strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name)); /* Now, set up the PSC for SMBus PIO mode. */ sp = (volatile psc_smb_t *)priv->psc_base; sp->psc_ctrl = PSC_CTRL_DISABLE; au_sync(); sp->psc_sel = PSC_SEL_PS_SMBUSMODE; sp->psc_smbcfg = 0; au_sync(); sp->psc_ctrl = PSC_CTRL_ENABLE; au_sync(); do { stat = sp->psc_smbstat; au_sync(); } while ((stat & PSC_SMBSTAT_SR) == 0); sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | PSC_SMBCFG_DD_DISABLE); /* Divide by 8 to get a 6.25 MHz clock. The later protocol * timings are based on this clock. */ sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); sp->psc_smbmsk = PSC_SMBMSK_ALLMASK; au_sync(); /* Set the protocol timer values. See Table 71 in the * Au1550 Data Book for standard timing values. */ sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \ PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \ PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \ PSC_SMBTMR_SET_CH(15); au_sync(); sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE; do { stat = sp->psc_smbstat; au_sync(); } while ((stat & PSC_SMBSTAT_DR) == 0); ret = i2c_add_numbered_adapter(&priv->adap); if (ret == 0) { platform_set_drvdata(pdev, priv); return 0; } /* disable the PSC */ sp->psc_smbcfg = 0; sp->psc_ctrl = PSC_CTRL_DISABLE; au_sync(); release_resource(priv->ioarea); kfree(priv->ioarea); out_mem: kfree(priv); out: return ret; }