diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-05-30 17:27:04 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-05-30 22:18:10 -0400 |
commit | 37b5a60335305e46be93c2eb904c8b5be7aba5f6 (patch) | |
tree | 4bda528e3493a5a3a57950b37dc465e593697182 /drivers/net/sfc/sfe4001.c | |
parent | 9e833be3a13aa64e1f3dc50ce0ad95278212511d (diff) |
sfc: Use kernel I2C system and i2c-algo-bit driver
Remove our own implementation of I2C bit-banging.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc/sfe4001.c')
-rw-r--r-- | drivers/net/sfc/sfe4001.c | 126 |
1 files changed, 66 insertions, 60 deletions
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 66a0d1442aba..b27849523990 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c | |||
@@ -106,28 +106,27 @@ | |||
106 | 106 | ||
107 | static const u8 xgphy_max_temperature = 90; | 107 | static const u8 xgphy_max_temperature = 90; |
108 | 108 | ||
109 | void sfe4001_poweroff(struct efx_nic *efx) | 109 | static void sfe4001_poweroff(struct efx_nic *efx) |
110 | { | 110 | { |
111 | struct efx_i2c_interface *i2c = &efx->i2c; | 111 | struct i2c_client *ioexp_client = efx->board_info.ioexp_client; |
112 | struct i2c_client *hwmon_client = efx->board_info.hwmon_client; | ||
112 | 113 | ||
113 | u8 cfg, out, in; | 114 | /* Turn off all power rails and disable outputs */ |
115 | i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff); | ||
116 | i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff); | ||
117 | i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff); | ||
114 | 118 | ||
115 | EFX_INFO(efx, "%s\n", __func__); | 119 | /* Clear any over-temperature alert */ |
116 | 120 | i2c_smbus_read_byte_data(hwmon_client, RSL); | |
117 | /* Turn off all power rails */ | 121 | } |
118 | out = 0xff; | ||
119 | efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | ||
120 | |||
121 | /* Disable port 1 outputs on IO expander */ | ||
122 | cfg = 0xff; | ||
123 | efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); | ||
124 | 122 | ||
125 | /* Disable port 0 outputs on IO expander */ | 123 | static void sfe4001_fini(struct efx_nic *efx) |
126 | cfg = 0xff; | 124 | { |
127 | efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); | 125 | EFX_INFO(efx, "%s\n", __func__); |
128 | 126 | ||
129 | /* Clear any over-temperature alert */ | 127 | sfe4001_poweroff(efx); |
130 | efx_i2c_read(i2c, MAX6647, RSL, &in, 1); | 128 | i2c_unregister_device(efx->board_info.ioexp_client); |
129 | i2c_unregister_device(efx->board_info.hwmon_client); | ||
131 | } | 130 | } |
132 | 131 | ||
133 | /* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected | 132 | /* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected |
@@ -143,14 +142,26 @@ MODULE_PARM_DESC(phy_flash_cfg, | |||
143 | * be turned on before the PHY can be used. | 142 | * be turned on before the PHY can be used. |
144 | * Context: Process context, rtnl lock held | 143 | * Context: Process context, rtnl lock held |
145 | */ | 144 | */ |
146 | int sfe4001_poweron(struct efx_nic *efx) | 145 | int sfe4001_init(struct efx_nic *efx) |
147 | { | 146 | { |
148 | struct efx_i2c_interface *i2c = &efx->i2c; | 147 | struct i2c_client *hwmon_client, *ioexp_client; |
149 | unsigned int count; | 148 | unsigned int count; |
150 | int rc; | 149 | int rc; |
151 | u8 out, in, cfg; | 150 | u8 out; |
152 | efx_dword_t reg; | 151 | efx_dword_t reg; |
153 | 152 | ||
153 | hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647); | ||
154 | if (!hwmon_client) | ||
155 | return -EIO; | ||
156 | efx->board_info.hwmon_client = hwmon_client; | ||
157 | |||
158 | ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539); | ||
159 | if (!ioexp_client) { | ||
160 | rc = -EIO; | ||
161 | goto fail_hwmon; | ||
162 | } | ||
163 | efx->board_info.ioexp_client = ioexp_client; | ||
164 | |||
154 | /* 10Xpress has fixed-function LED pins, so there is no board-specific | 165 | /* 10Xpress has fixed-function LED pins, so there is no board-specific |
155 | * blink code. */ | 166 | * blink code. */ |
156 | efx->board_info.blink = tenxpress_phy_blink; | 167 | efx->board_info.blink = tenxpress_phy_blink; |
@@ -166,44 +177,45 @@ int sfe4001_poweron(struct efx_nic *efx) | |||
166 | falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC); | 177 | falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC); |
167 | udelay(10); | 178 | udelay(10); |
168 | 179 | ||
180 | efx->board_info.fini = sfe4001_fini; | ||
181 | |||
169 | /* Set DSP over-temperature alert threshold */ | 182 | /* Set DSP over-temperature alert threshold */ |
170 | EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature); | 183 | EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature); |
171 | rc = efx_i2c_write(i2c, MAX6647, WLHO, | 184 | rc = i2c_smbus_write_byte_data(hwmon_client, WLHO, |
172 | &xgphy_max_temperature, 1); | 185 | xgphy_max_temperature); |
173 | if (rc) | 186 | if (rc) |
174 | goto fail1; | 187 | goto fail_ioexp; |
175 | 188 | ||
176 | /* Read it back and verify */ | 189 | /* Read it back and verify */ |
177 | rc = efx_i2c_read(i2c, MAX6647, RLHN, &in, 1); | 190 | rc = i2c_smbus_read_byte_data(hwmon_client, RLHN); |
178 | if (rc) | 191 | if (rc < 0) |
179 | goto fail1; | 192 | goto fail_ioexp; |
180 | if (in != xgphy_max_temperature) { | 193 | if (rc != xgphy_max_temperature) { |
181 | rc = -EFAULT; | 194 | rc = -EFAULT; |
182 | goto fail1; | 195 | goto fail_ioexp; |
183 | } | 196 | } |
184 | 197 | ||
185 | /* Clear any previous over-temperature alert */ | 198 | /* Clear any previous over-temperature alert */ |
186 | rc = efx_i2c_read(i2c, MAX6647, RSL, &in, 1); | 199 | rc = i2c_smbus_read_byte_data(hwmon_client, RSL); |
187 | if (rc) | 200 | if (rc < 0) |
188 | goto fail1; | 201 | goto fail_ioexp; |
189 | 202 | ||
190 | /* Enable port 0 and port 1 outputs on IO expander */ | 203 | /* Enable port 0 and port 1 outputs on IO expander */ |
191 | cfg = 0x00; | 204 | rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00); |
192 | rc = efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); | ||
193 | if (rc) | 205 | if (rc) |
194 | goto fail1; | 206 | goto fail_ioexp; |
195 | cfg = 0xff & ~(1 << P1_SPARE_LBN); | 207 | rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, |
196 | rc = efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); | 208 | 0xff & ~(1 << P1_SPARE_LBN)); |
197 | if (rc) | 209 | if (rc) |
198 | goto fail2; | 210 | goto fail_on; |
199 | 211 | ||
200 | /* Turn all power off then wait 1 sec. This ensures PHY is reset */ | 212 | /* Turn all power off then wait 1 sec. This ensures PHY is reset */ |
201 | out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) | | 213 | out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) | |
202 | (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) | | 214 | (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) | |
203 | (0 << P0_EN_1V0X_LBN)); | 215 | (0 << P0_EN_1V0X_LBN)); |
204 | rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 216 | rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); |
205 | if (rc) | 217 | if (rc) |
206 | goto fail3; | 218 | goto fail_on; |
207 | 219 | ||
208 | schedule_timeout_uninterruptible(HZ); | 220 | schedule_timeout_uninterruptible(HZ); |
209 | count = 0; | 221 | count = 0; |
@@ -215,26 +227,26 @@ int sfe4001_poweron(struct efx_nic *efx) | |||
215 | if (sfe4001_phy_flash_cfg) | 227 | if (sfe4001_phy_flash_cfg) |
216 | out |= 1 << P0_EN_3V3X_LBN; | 228 | out |= 1 << P0_EN_3V3X_LBN; |
217 | 229 | ||
218 | rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 230 | rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); |
219 | if (rc) | 231 | if (rc) |
220 | goto fail3; | 232 | goto fail_on; |
221 | msleep(10); | 233 | msleep(10); |
222 | 234 | ||
223 | /* Turn on 1V power rail */ | 235 | /* Turn on 1V power rail */ |
224 | out &= ~(1 << P0_EN_1V0X_LBN); | 236 | out &= ~(1 << P0_EN_1V0X_LBN); |
225 | rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 237 | rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); |
226 | if (rc) | 238 | if (rc) |
227 | goto fail3; | 239 | goto fail_on; |
228 | 240 | ||
229 | EFX_INFO(efx, "waiting for power (attempt %d)...\n", count); | 241 | EFX_INFO(efx, "waiting for power (attempt %d)...\n", count); |
230 | 242 | ||
231 | schedule_timeout_uninterruptible(HZ); | 243 | schedule_timeout_uninterruptible(HZ); |
232 | 244 | ||
233 | /* Check DSP is powered */ | 245 | /* Check DSP is powered */ |
234 | rc = efx_i2c_read(i2c, PCA9539, P1_IN, &in, 1); | 246 | rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN); |
235 | if (rc) | 247 | if (rc < 0) |
236 | goto fail3; | 248 | goto fail_on; |
237 | if (in & (1 << P1_AFE_PWD_LBN)) | 249 | if (rc & (1 << P1_AFE_PWD_LBN)) |
238 | goto done; | 250 | goto done; |
239 | 251 | ||
240 | /* DSP doesn't look powered in flash config mode */ | 252 | /* DSP doesn't look powered in flash config mode */ |
@@ -244,23 +256,17 @@ int sfe4001_poweron(struct efx_nic *efx) | |||
244 | 256 | ||
245 | EFX_INFO(efx, "timed out waiting for power\n"); | 257 | EFX_INFO(efx, "timed out waiting for power\n"); |
246 | rc = -ETIMEDOUT; | 258 | rc = -ETIMEDOUT; |
247 | goto fail3; | 259 | goto fail_on; |
248 | 260 | ||
249 | done: | 261 | done: |
250 | EFX_INFO(efx, "PHY is powered on\n"); | 262 | EFX_INFO(efx, "PHY is powered on\n"); |
251 | return 0; | 263 | return 0; |
252 | 264 | ||
253 | fail3: | 265 | fail_on: |
254 | /* Turn off all power rails */ | 266 | sfe4001_poweroff(efx); |
255 | out = 0xff; | 267 | fail_ioexp: |
256 | efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 268 | i2c_unregister_device(ioexp_client); |
257 | /* Disable port 1 outputs on IO expander */ | 269 | fail_hwmon: |
258 | out = 0xff; | 270 | i2c_unregister_device(hwmon_client); |
259 | efx_i2c_write(i2c, PCA9539, P1_CONFIG, &out, 1); | ||
260 | fail2: | ||
261 | /* Disable port 0 outputs on IO expander */ | ||
262 | out = 0xff; | ||
263 | efx_i2c_write(i2c, PCA9539, P0_CONFIG, &out, 1); | ||
264 | fail1: | ||
265 | return rc; | 271 | return rc; |
266 | } | 272 | } |