PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/uts/sun4u/io/envctrl_targets.c

https://bitbucket.org/nexenta/illumos-nexenta
C | 1127 lines | 641 code | 181 blank | 305 comment | 166 complexity | a89765b2c183f8cf7308409f3aea7bce MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-1.0, GPL-3.0, LGPL-3.0, BSD-2-Clause, AGPL-3.0, BSD-3-Clause, GPL-2.0, LGPL-2.1, 0BSD
  1. /*
  2. * CDDL HEADER START
  3. *
  4. * The contents of this file are subject to the terms of the
  5. * Common Development and Distribution License (the "License").
  6. * You may not use this file except in compliance with the License.
  7. *
  8. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  9. * or http://www.opensolaris.org/os/licensing.
  10. * See the License for the specific language governing permissions
  11. * and limitations under the License.
  12. *
  13. * When distributing Covered Code, include this CDDL HEADER in each
  14. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15. * If applicable, add the following below this CDDL HEADER, with the
  16. * fields enclosed by brackets "[]" replaced with your own identifying
  17. * information: Portions Copyright [yyyy] [name of copyright owner]
  18. *
  19. * CDDL HEADER END
  20. */
  21. /*
  22. * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
  23. * Use is subject to license terms.
  24. */
  25. #pragma ident "%Z%%M% %I% %E% SMI"
  26. /*
  27. * Low level environmental control routines.
  28. * These routines implement the I2C bus protocol.
  29. */
  30. #define EHC_SUCCESS 0
  31. #define EHC_FAILURE (-1)
  32. #define EHC_NO_SLAVE_ACK 3
  33. #define EHC_MAX_WAIT 100 /* decimal */
  34. #define EHC_S1_PIN 0x80
  35. #define EHC_S1_ES1 0x20
  36. #define EHC_S1_ES0 0x40
  37. #define EHC_S1_NBB 0x01
  38. #define EHC_S1_ACK 0x01
  39. #define EHC_S1_STA 0x04
  40. #define EHC_S1_STO 0x02
  41. #define EHC_S1_LRB 0x08
  42. #define EHC_S1_BER 0x10
  43. #define EHC_S1_LAB 0x02
  44. #define EHC_S1_AAS 0x04
  45. #define EHC_S1_AD0 0x08
  46. #define EHC_S1_STS 0x20
  47. #define EHC_S0_OWN 0x55
  48. #define EHC_S0_CLK 0x1d
  49. #define EHC_BYTE_READ 0x01
  50. #define EHC_LONGEST_MSG 200000 /* 200 ms */
  51. #define DUMMY_WRITE_ADDR 0x20
  52. #define DUMMY_WRITE_DATA 0x00
  53. /*
  54. * PCF8591 Chip Used for temperature sensors
  55. *
  56. * Addressing Register definition.
  57. * A0-A2 valid range is 0-7
  58. *
  59. * ------------------------------------------------
  60. * | 1 | 0 | 0 | 1 | A2 | A1 | A0 | R/W |
  61. * ------------------------------------------------
  62. */
  63. #define EHC_PCF8591_MAX_DEVS 0x08
  64. #define EHC_DEV0 0x00
  65. #define EHC_DEV1 0x02
  66. #define EHC_DEV2 0x04
  67. #define EHC_DEV3 0x06
  68. #define EHC_DEV4 0x08
  69. #define EHC_DEV5 0x0A
  70. #define EHC_DEV6 0x0C
  71. #define EHC_DEV7 0x0E
  72. /*
  73. * CONTROL OF CHIP
  74. * PCF8591 Temp sensing control register definitions
  75. *
  76. * ---------------------------------------------
  77. * | 0 | AOE | X | X | 0 | AIF | X | X |
  78. * ---------------------------------------------
  79. * AOE = Analog out enable.. not used on out implementation
  80. * 5 & 4 = Analog Input Programming.. see data sheet for bits..
  81. *
  82. * AIF = Auto increment flag
  83. * bits 1 & 0 are for the Chennel number.
  84. */
  85. #define EHC_PCF8591_ANALOG_OUTPUT_EN 0x40
  86. #define EHC_PCF8591_ANALOG_INPUT_EN 0x00
  87. #define EHC_PCF8591_READ_BIT 0x01
  88. #define EHC_PCF8591_AUTO_INCR 0x04
  89. #define EHC_PCF8591_OSCILATOR 0x40
  90. #define EHC_PCF8591_MAX_PORTS 0x04
  91. #define EHC_PCF8591_CH_0 0x00
  92. #define EHC_PCF8591_CH_1 0x01
  93. #define EHC_PCF8591_CH_2 0x02
  94. #define EHC_PCF8591_CH_3 0x03
  95. /*
  96. * PCF8574 Fan Fail, Power Supply Fail Detector
  97. * This device is driven by interrupts. Each time it interrupts
  98. * you must look at the CSR to see which ports caused the interrupt
  99. * they are indicated by a 1.
  100. *
  101. * Address map of this chip
  102. *
  103. * -------------------------------------------
  104. * | 0 | 1 | 1 | 1 | A2 | A1 | A0 | 0 |
  105. * -------------------------------------------
  106. *
  107. */
  108. #define EHC_PCF8574_PORT0 0x01
  109. #define EHC_PCF8574_PORT1 0x02
  110. #define EHC_PCF8574_PORT2 0x04
  111. #define EHC_PCF8574_PORT3 0x08
  112. #define EHC_PCF8574_PORT4 0x10
  113. #define EHC_PCF8574_PORT5 0x20
  114. #define EHC_PCF8574_PORT6 0x40
  115. #define EHC_PCF8574_PORT7 0x80
  116. /*
  117. * Defines for the PCF8583 Clock Calendar Chip.
  118. */
  119. #define EHC_PCF8583_READ_BIT 0x01
  120. struct ehc_pcd8584_regs {
  121. uint8_t s0; /* Own Address S0' */
  122. uint8_t s1; /* Control Status register */
  123. uint8_t clock_s2; /* Clock programming register */
  124. };
  125. struct ehc_envcunit {
  126. struct ehc_pcd8584_regs *bus_ctl_regs;
  127. ddi_acc_handle_t ctlr_handle;
  128. kmutex_t umutex;
  129. };
  130. int ehc_debug = 0;
  131. #define DCMN_ERR if (ehc_debug & 0x1) cmn_err
  132. #define DCMN2_ERR if (ehc_debug & 0x2) cmn_err
  133. /*
  134. * Prototypes for routines used in other modules.
  135. */
  136. void ehc_init_pcf8584(struct ehc_envcunit *);
  137. int ehc_read_tda8444(struct ehc_envcunit *ehcp);
  138. int ehc_write_tda8444(struct ehc_envcunit *, int, int, int, uint8_t *, int);
  139. int ehc_write_pcf8591(struct ehc_envcunit *, int, int, int, int, int,
  140. uint8_t *, int);
  141. int ehc_read_pcf8591(struct ehc_envcunit *, int, int, int, int, int,
  142. uint8_t *, int);
  143. int ehc_read_pcf8574a(struct ehc_envcunit *, int, uint8_t *, int);
  144. int ehc_write_pcf8574a(struct ehc_envcunit *, int, uint8_t *, int);
  145. int ehc_read_pcf8574(struct ehc_envcunit *, int, uint8_t *, int);
  146. int ehc_write_pcf8574(struct ehc_envcunit *, int, uint8_t *, int);
  147. int ehc_read_lm75(struct ehc_envcunit *, int, uint8_t *, int);
  148. int ehc_write_pcf8583(struct ehc_envcunit *, int, uint8_t *, int);
  149. /*
  150. * Prototypes for routines used only in this source module.
  151. */
  152. static int ehc_start_pcf8584(struct ehc_envcunit *, uint8_t);
  153. static void ehc_stop_pcf8584(struct ehc_envcunit *);
  154. static int ehc_read_pcf8584(struct ehc_envcunit *, uint8_t *);
  155. static int ehc_write_pcf8584(struct ehc_envcunit *, uint8_t);
  156. static int ehc_after_read_pcf8584(struct ehc_envcunit *, uint8_t *);
  157. /*
  158. * put host interface into master mode
  159. */
  160. static int
  161. ehc_start_pcf8584(struct ehc_envcunit *ehcp, uint8_t byteaddress)
  162. {
  163. uint8_t poll_status;
  164. uint8_t discard;
  165. int i;
  166. /* wait if bus is busy */
  167. i = 0;
  168. do {
  169. drv_usecwait(1000);
  170. poll_status =
  171. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  172. i++;
  173. } while (((poll_status & EHC_S1_NBB) == 0) && i < EHC_MAX_WAIT);
  174. if (i == EHC_MAX_WAIT) {
  175. DCMN_ERR(CE_WARN, "ehc_start_pcf8584(): busy bit clear failed");
  176. return (EHC_FAILURE);
  177. }
  178. if (poll_status & EHC_S1_BER) {
  179. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()1: Bus error");
  180. ehc_init_pcf8584(ehcp);
  181. return (EHC_FAILURE);
  182. }
  183. if (poll_status & EHC_S1_LAB) {
  184. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()1: Lost Arbitration");
  185. ehc_init_pcf8584(ehcp);
  186. return (EHC_FAILURE);
  187. }
  188. /*
  189. * This is a dummy arbitration using the lowest unused address
  190. * possible. This step allows the PCF8584 to always win arbitration
  191. * except in the case of "general call" being issued by the other
  192. * master.
  193. */
  194. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, DUMMY_WRITE_ADDR);
  195. /* generate the "start condition" and clock out the slave address */
  196. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
  197. EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK);
  198. /* wait for completion of transmission */
  199. i = 0;
  200. do {
  201. drv_usecwait(1000);
  202. poll_status =
  203. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  204. i++;
  205. } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
  206. if (i == EHC_MAX_WAIT) {
  207. DCMN_ERR(CE_WARN, "ehc_start_pcf8584_5(): read of S1 failed");
  208. return (EHC_FAILURE);
  209. }
  210. if (poll_status & EHC_S1_BER) {
  211. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()5: Bus error");
  212. ehc_init_pcf8584(ehcp);
  213. return (EHC_FAILURE);
  214. }
  215. if (poll_status & EHC_S1_LAB) {
  216. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()5: Lost Arbitration");
  217. ehc_init_pcf8584(ehcp);
  218. return (EHC_FAILURE);
  219. }
  220. /* dummy write */
  221. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, DUMMY_WRITE_DATA);
  222. /* wait for completion of transmission */
  223. i = 0;
  224. do {
  225. drv_usecwait(1000);
  226. poll_status =
  227. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  228. i++;
  229. } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
  230. if (i == EHC_MAX_WAIT) {
  231. DCMN_ERR(CE_WARN, "ehc_start_pcf8584(): read of S1 failed");
  232. return (EHC_FAILURE);
  233. }
  234. if (poll_status & EHC_S1_BER) {
  235. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()4: Bus error");
  236. ehc_init_pcf8584(ehcp);
  237. return (EHC_FAILURE);
  238. }
  239. if (poll_status & EHC_S1_LAB) {
  240. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()4: Lost Arbitration");
  241. ehc_init_pcf8584(ehcp);
  242. return (EHC_FAILURE);
  243. }
  244. /*
  245. * generate the repeated "start condition" and
  246. * clock out the slave address
  247. */
  248. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
  249. EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK);
  250. /* load the slave address */
  251. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, byteaddress);
  252. /* wait for completion of transmission */
  253. i = 0;
  254. do {
  255. drv_usecwait(1000);
  256. poll_status =
  257. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  258. i++;
  259. } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
  260. if (i == EHC_MAX_WAIT) {
  261. DCMN_ERR(CE_WARN, "ehc_start_pcf8584(): read of S1 failed");
  262. return (EHC_FAILURE);
  263. }
  264. if (poll_status & EHC_S1_BER) {
  265. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()2: Bus error");
  266. ehc_init_pcf8584(ehcp);
  267. return (EHC_FAILURE);
  268. }
  269. if (poll_status & EHC_S1_LAB) {
  270. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()2: Lost Arbitration");
  271. ehc_init_pcf8584(ehcp);
  272. return (EHC_FAILURE);
  273. }
  274. if (poll_status & EHC_S1_LRB) {
  275. DCMN_ERR(CE_WARN, "ehc_start_pcf8584(): No slave ACK");
  276. return (EHC_NO_SLAVE_ACK);
  277. }
  278. /*
  279. * If this is a read we are setting up for (as indicated by
  280. * the least significant byte being set), read
  281. * and discard the first byte off the bus - this
  282. * is the slave address.
  283. */
  284. i = 0;
  285. if (byteaddress & EHC_BYTE_READ) {
  286. discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
  287. #ifdef lint
  288. discard = discard;
  289. #endif
  290. /* wait for completion of transmission */
  291. do {
  292. drv_usecwait(1000);
  293. poll_status =
  294. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  295. i++;
  296. } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
  297. if (i == EHC_MAX_WAIT) {
  298. DCMN_ERR(CE_WARN,
  299. "ehc_start_pcf8584(): read of S1 failed");
  300. return (EHC_FAILURE);
  301. }
  302. if (poll_status & EHC_S1_BER) {
  303. DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()3: Bus error");
  304. ehc_init_pcf8584(ehcp);
  305. return (EHC_FAILURE);
  306. }
  307. if (poll_status & EHC_S1_LAB) {
  308. DCMN2_ERR(CE_WARN,
  309. "ehc_start_pcf8584()3: Lost Arbitration");
  310. ehc_init_pcf8584(ehcp);
  311. return (EHC_FAILURE);
  312. }
  313. }
  314. return (EHC_SUCCESS);
  315. }
  316. /*
  317. * put host interface into slave/receiver mode
  318. */
  319. static void
  320. ehc_stop_pcf8584(struct ehc_envcunit *ehcp)
  321. {
  322. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
  323. EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STO | EHC_S1_ACK);
  324. }
  325. static int
  326. ehc_read_pcf8584(struct ehc_envcunit *ehcp, uint8_t *data)
  327. {
  328. uint8_t poll_status;
  329. int i = 0;
  330. /* Read the byte of interest */
  331. *data = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
  332. /* wait for completion of transmission */
  333. do {
  334. drv_usecwait(1000);
  335. poll_status =
  336. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  337. i++;
  338. } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
  339. if (i == EHC_MAX_WAIT) {
  340. DCMN_ERR(CE_WARN, "ehc_read_pcf8584(): read of S1 failed");
  341. return (EHC_FAILURE);
  342. }
  343. if (poll_status & EHC_S1_BER) {
  344. DCMN2_ERR(CE_WARN, "ehc_read_pcf8584(): Bus error");
  345. ehc_init_pcf8584(ehcp);
  346. return (EHC_FAILURE);
  347. }
  348. if (poll_status & EHC_S1_LAB) {
  349. DCMN2_ERR(CE_WARN, "ehc_read_pcf8584(): Lost Arbitration");
  350. ehc_init_pcf8584(ehcp);
  351. return (EHC_FAILURE);
  352. }
  353. return (EHC_SUCCESS);
  354. }
  355. /*
  356. * host interface is in transmitter state, thus mode is master/transmitter
  357. * NOTE to Bill: this check the LRB bit (only done in transmit mode).
  358. */
  359. static int
  360. ehc_write_pcf8584(struct ehc_envcunit *ehcp, uint8_t data)
  361. {
  362. uint8_t poll_status;
  363. int i = 0;
  364. /* send the data, EHC_S1_PIN should go to "1" immediately */
  365. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, data);
  366. /* wait for completion of transmission */
  367. do {
  368. drv_usecwait(1000);
  369. poll_status =
  370. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  371. i++;
  372. } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
  373. if (i == EHC_MAX_WAIT) {
  374. DCMN_ERR(CE_WARN, "ehc_write_pcf8584(): read of S1 failed");
  375. return (EHC_FAILURE);
  376. }
  377. if (poll_status & EHC_S1_BER) {
  378. DCMN2_ERR(CE_WARN, "ehc_write_pcf8584(): Bus error");
  379. ehc_init_pcf8584(ehcp);
  380. return (EHC_FAILURE);
  381. }
  382. if (poll_status & EHC_S1_LAB) {
  383. DCMN2_ERR(CE_WARN, "ehc_write_pcf8584(): Lost Arbitration");
  384. ehc_init_pcf8584(ehcp);
  385. return (EHC_FAILURE);
  386. }
  387. if (poll_status & EHC_S1_LRB) {
  388. DCMN_ERR(CE_WARN, "ehc_write_pcf8584(): No slave ACK");
  389. return (EHC_NO_SLAVE_ACK);
  390. }
  391. return (EHC_SUCCESS);
  392. }
  393. static int
  394. ehc_after_read_pcf8584(struct ehc_envcunit *ehcp, uint8_t *data)
  395. {
  396. uint8_t discard;
  397. uint8_t poll_status;
  398. int i = 0;
  399. /* set ACK in register S1 to 0 */
  400. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, EHC_S1_ES0);
  401. /*
  402. * Read the "byte-before-the-last-byte" - sets PIN bit to '1'
  403. */
  404. *data = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
  405. /* wait for completion of transmission */
  406. do {
  407. drv_usecwait(1000);
  408. poll_status =
  409. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  410. i++;
  411. } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
  412. if (i == EHC_MAX_WAIT) {
  413. DCMN_ERR(CE_WARN, "ehc_after_rd_pcf8584(): read of S1 failed");
  414. return (EHC_FAILURE);
  415. }
  416. if (poll_status & EHC_S1_BER) {
  417. DCMN2_ERR(CE_WARN, "ehc_after_rd_pcf8584(): Bus error");
  418. ehc_init_pcf8584(ehcp);
  419. return (EHC_FAILURE);
  420. }
  421. if (poll_status & EHC_S1_LAB) {
  422. DCMN2_ERR(CE_WARN, "ehc_after_rd_pcf8584(): Lost Arbitration");
  423. ehc_init_pcf8584(ehcp);
  424. return (EHC_FAILURE);
  425. }
  426. /*
  427. * Generate the "stop" condition.
  428. */
  429. ehc_stop_pcf8584(ehcp);
  430. /*
  431. * Read the "last" byte.
  432. */
  433. discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
  434. #ifdef lint
  435. discard = discard;
  436. #endif
  437. return (EHC_SUCCESS);
  438. }
  439. /*
  440. * Below this comment are the externally visible routines comprising the API
  441. */
  442. /*
  443. * Initialize the 8584 chip
  444. */
  445. void
  446. ehc_init_pcf8584(struct ehc_envcunit *ehcp)
  447. {
  448. /*
  449. * Writing PIN bit of S1 causes software reset.
  450. * The next write to S0 will be S0' "own address".
  451. */
  452. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, EHC_S1_PIN);
  453. /*
  454. * Write the address which the controller chip will use
  455. * (when addressed as a slave) on the I2C bus.
  456. * DAF - should own address be passed as argument?
  457. */
  458. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, EHC_S0_OWN);
  459. /*
  460. * Writing PIN bit and ES1 bit of S1 causes software
  461. * reset and selects the S2 register for writing.
  462. * Now, the next write to S0 will be the S2 clock
  463. * control register.
  464. */
  465. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
  466. EHC_S1_PIN | EHC_S1_ES1);
  467. /*
  468. * Write the value into register that sets internal system clock
  469. * to 12 Mhz, and the I2C bus rate (SCL) to 9 Khz.
  470. * DAF - should these be parameters?
  471. */
  472. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, EHC_S0_CLK);
  473. /*
  474. * Writing PIN bit causes software reset and the ES0 bit
  475. * selects the (S0) register for reading/writing. The ACK
  476. * bit being set causes controller to send ACK after each
  477. * byte.
  478. */
  479. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
  480. EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_ACK);
  481. /*
  482. * Multi-Master: Wait for a period of time equal to the
  483. * longest I2C message. This accounts for the case
  484. * where multiple controllers and, if this particular one
  485. * is "lagging", misses the BB (bus busy) condition.
  486. * DAF - What does this need?
  487. * We wait 200 ms since the longest transaction at this time
  488. * on the i2c bus is a 256 byte read from the seprom which takes
  489. * about 75 ms. Some additional buffer does no harm to the driver.
  490. */
  491. drv_usecwait(EHC_LONGEST_MSG);
  492. }
  493. int
  494. ehc_read_tda8444(struct ehc_envcunit *ehcp)
  495. {
  496. #ifdef lint
  497. ehcp = ehcp;
  498. #endif
  499. return (EHC_FAILURE);
  500. }
  501. /*
  502. * Write to the TDA8444 chip.
  503. * byteaddress = chip type base address | chip offset address.
  504. */
  505. int
  506. ehc_write_tda8444(struct ehc_envcunit *ehcp, int byteaddress, int instruction,
  507. int subaddress, uint8_t *buf, int size)
  508. {
  509. uint8_t control;
  510. int i, status;
  511. ASSERT((byteaddress & 0x1) == 0);
  512. ASSERT(subaddress < 8);
  513. ASSERT(instruction == 0xf || instruction == 0x0);
  514. ASSERT(MUTEX_HELD(&ehcp->umutex));
  515. control = (instruction << 4) | subaddress;
  516. if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
  517. if (status == EHC_NO_SLAVE_ACK) {
  518. /*
  519. * Send the "stop" condition.
  520. */
  521. ehc_stop_pcf8584(ehcp);
  522. }
  523. return (EHC_FAILURE);
  524. }
  525. if ((status = ehc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) {
  526. if (status == EHC_NO_SLAVE_ACK) {
  527. /*
  528. * Send the "stop" condition.
  529. */
  530. ehc_stop_pcf8584(ehcp);
  531. }
  532. return (EHC_FAILURE);
  533. }
  534. for (i = 0; i < size; i++) {
  535. if ((status = ehc_write_pcf8584(ehcp, (buf[i] & 0x3f))) !=
  536. EHC_SUCCESS) {
  537. if (status == EHC_NO_SLAVE_ACK)
  538. ehc_stop_pcf8584(ehcp);
  539. return (EHC_FAILURE);
  540. }
  541. }
  542. ehc_stop_pcf8584(ehcp);
  543. return (EHC_SUCCESS);
  544. }
  545. /*
  546. * Read from PCF8574A chip.
  547. * byteaddress = chip type base address | chip offset address.
  548. */
  549. int
  550. ehc_read_pcf8574a(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
  551. int size)
  552. {
  553. int i;
  554. int status;
  555. uint8_t discard;
  556. ASSERT((byteaddress & 0x1) == 0);
  557. ASSERT(MUTEX_HELD(&ehcp->umutex));
  558. /*
  559. * Put the bus into the start condition
  560. */
  561. if ((status = ehc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
  562. EHC_SUCCESS) {
  563. if (status == EHC_NO_SLAVE_ACK) {
  564. /*
  565. * Send the "stop" condition.
  566. */
  567. ehc_stop_pcf8584(ehcp);
  568. /*
  569. * Read the last byte - discard it.
  570. */
  571. discard =
  572. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
  573. #ifdef lint
  574. discard = discard;
  575. #endif
  576. }
  577. return (EHC_FAILURE);
  578. }
  579. for (i = 0; i < size - 1; i++) {
  580. if ((status = ehc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
  581. return (EHC_FAILURE);
  582. }
  583. }
  584. /*
  585. * Handle the part of the bus protocol which comes
  586. * after a read, including reading the last byte.
  587. */
  588. if (ehc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
  589. return (EHC_FAILURE);
  590. }
  591. return (EHC_SUCCESS);
  592. }
  593. /*
  594. * Write to the PCF8574A chip.
  595. * byteaddress = chip type base address | chip offset address.
  596. */
  597. int
  598. ehc_write_pcf8574a(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
  599. int size)
  600. {
  601. int i;
  602. int status;
  603. ASSERT((byteaddress & 0x1) == 0);
  604. ASSERT(MUTEX_HELD(&ehcp->umutex));
  605. /*
  606. * Put the bus into the start condition (write)
  607. */
  608. if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
  609. if (status == EHC_NO_SLAVE_ACK) {
  610. /*
  611. * Send the "stop" condition.
  612. */
  613. ehc_stop_pcf8584(ehcp);
  614. }
  615. return (EHC_FAILURE);
  616. }
  617. /*
  618. * Send the data - poll as needed.
  619. */
  620. for (i = 0; i < size; i++) {
  621. if ((status = ehc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
  622. if (status == EHC_NO_SLAVE_ACK)
  623. ehc_stop_pcf8584(ehcp);
  624. return (EHC_FAILURE);
  625. }
  626. }
  627. /*
  628. * Transmission complete - generate stop condition and
  629. * put device back into slave receiver mode.
  630. */
  631. ehc_stop_pcf8584(ehcp);
  632. return (EHC_SUCCESS);
  633. }
  634. /*
  635. * Read from the PCF8574 chip.
  636. * byteaddress = chip type base address | chip offset address.
  637. */
  638. int
  639. ehc_read_pcf8574(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
  640. int size)
  641. {
  642. int i;
  643. int status;
  644. uint8_t discard;
  645. ASSERT((byteaddress & 0x1) == 0);
  646. ASSERT(MUTEX_HELD(&ehcp->umutex));
  647. /*
  648. * Put the bus into the start condition
  649. */
  650. if ((status = ehc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
  651. EHC_SUCCESS) {
  652. if (status == EHC_NO_SLAVE_ACK) {
  653. /*
  654. * Send the "stop" condition.
  655. */
  656. ehc_stop_pcf8584(ehcp);
  657. /*
  658. * Read the last byte - discard it.
  659. */
  660. discard =
  661. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
  662. #ifdef lint
  663. discard = discard;
  664. #endif
  665. }
  666. return (EHC_FAILURE);
  667. }
  668. for (i = 0; i < size - 1; i++) {
  669. if ((status = ehc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
  670. return (EHC_FAILURE);
  671. }
  672. }
  673. /*
  674. * Handle the part of the bus protocol which comes
  675. * after a read.
  676. */
  677. if (ehc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
  678. return (EHC_FAILURE);
  679. }
  680. return (EHC_SUCCESS);
  681. }
  682. /*
  683. * Write to the PCF8574 chip.
  684. * byteaddress = chip type base address | chip offset address.
  685. */
  686. int
  687. ehc_write_pcf8574(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
  688. int size)
  689. {
  690. int i;
  691. int status;
  692. ASSERT((byteaddress & 0x1) == 0);
  693. ASSERT(MUTEX_HELD(&ehcp->umutex));
  694. /*
  695. * Put the bus into the start condition (write)
  696. */
  697. if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
  698. if (status == EHC_NO_SLAVE_ACK) {
  699. /*
  700. * Send the "stop" condition.
  701. */
  702. ehc_stop_pcf8584(ehcp);
  703. }
  704. return (EHC_FAILURE);
  705. }
  706. /*
  707. * Send the data - poll as needed.
  708. */
  709. for (i = 0; i < size; i++) {
  710. if ((status = ehc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
  711. if (status == EHC_NO_SLAVE_ACK)
  712. ehc_stop_pcf8584(ehcp);
  713. return (EHC_FAILURE);
  714. }
  715. }
  716. /*
  717. * Transmission complete - generate stop condition and
  718. * put device back into slave receiver mode.
  719. */
  720. ehc_stop_pcf8584(ehcp);
  721. return (EHC_SUCCESS);
  722. }
  723. /*
  724. * Read from the LM75
  725. * byteaddress = chip type base address | chip offset address.
  726. */
  727. int
  728. ehc_read_lm75(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
  729. int size)
  730. {
  731. int i;
  732. int status;
  733. uint8_t discard;
  734. ASSERT((byteaddress & 0x1) == 0);
  735. ASSERT(MUTEX_HELD(&ehcp->umutex));
  736. /*
  737. * Put the bus into the start condition
  738. */
  739. if ((status = ehc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
  740. EHC_SUCCESS) {
  741. if (status == EHC_NO_SLAVE_ACK) {
  742. /*
  743. * Send the stop condition.
  744. */
  745. ehc_stop_pcf8584(ehcp);
  746. /*
  747. * Read the last byte - discard it.
  748. */
  749. discard =
  750. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
  751. #ifdef lint
  752. discard = discard;
  753. #endif
  754. }
  755. return (EHC_FAILURE);
  756. }
  757. for (i = 0; i < size - 1; i++) {
  758. if ((status = ehc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
  759. return (EHC_FAILURE);
  760. }
  761. }
  762. /*
  763. * Handle the part of the bus protocol which comes
  764. * after a read.
  765. */
  766. if (ehc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
  767. return (EHC_FAILURE);
  768. }
  769. return (EHC_SUCCESS);
  770. }
  771. /*
  772. * Write to the PCF8583 chip.
  773. * byteaddress = chip type base address | chip offset address.
  774. */
  775. int
  776. ehc_write_pcf8583(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
  777. int size)
  778. {
  779. int i;
  780. int status;
  781. ASSERT((byteaddress & 0x1) == 0);
  782. ASSERT(MUTEX_HELD(&ehcp->umutex));
  783. if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
  784. if (status == EHC_NO_SLAVE_ACK) {
  785. /*
  786. * Send the "stop" condition.
  787. */
  788. ehc_stop_pcf8584(ehcp);
  789. }
  790. return (EHC_FAILURE);
  791. }
  792. /*
  793. * Send the data - poll as needed.
  794. */
  795. for (i = 0; i < size; i++) {
  796. if ((status = ehc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
  797. if (status == EHC_NO_SLAVE_ACK)
  798. ehc_stop_pcf8584(ehcp);
  799. return (EHC_FAILURE);
  800. }
  801. }
  802. /*
  803. * Transmission complete - generate stop condition and
  804. * put device back into slave receiver mode.
  805. */
  806. ehc_stop_pcf8584(ehcp);
  807. return (EHC_SUCCESS);
  808. }
  809. /*
  810. * Read from the PCF8591 chip.
  811. */
  812. int
  813. ehc_read_pcf8591(struct ehc_envcunit *ehcp, int byteaddress, int channel,
  814. int autoinc, int amode, int aenable, uint8_t *buf, int size)
  815. {
  816. int i;
  817. int status;
  818. register uint8_t control;
  819. uint8_t discard;
  820. ASSERT((byteaddress & 0x1) == 0);
  821. ASSERT(channel < 4);
  822. ASSERT(amode < 4);
  823. ASSERT(MUTEX_HELD(&ehcp->umutex));
  824. /*
  825. * Write the control word to the PCF8591.
  826. * Follow the control word with a repeated START byte
  827. * rather than a STOP so that reads can follow without giving
  828. * up the bus.
  829. */
  830. control = ((aenable << 6) | (amode << 4) | (autoinc << 2) | channel);
  831. if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
  832. if (status == EHC_NO_SLAVE_ACK) {
  833. ehc_stop_pcf8584(ehcp);
  834. }
  835. return (EHC_FAILURE);
  836. }
  837. if ((status = ehc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) {
  838. if (status == EHC_NO_SLAVE_ACK)
  839. ehc_stop_pcf8584(ehcp);
  840. return (EHC_FAILURE);
  841. }
  842. /*
  843. * The following two operations, 0x45 to S1, and the byteaddress
  844. * to S0, will result in a repeated START being sent out on the bus.
  845. * Refer to Fig.8 of Philips Semiconductors PCF8584 product spec.
  846. */
  847. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
  848. EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK);
  849. ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0,
  850. EHC_BYTE_READ | byteaddress);
  851. i = 0;
  852. do {
  853. drv_usecwait(1000);
  854. status =
  855. ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
  856. i++;
  857. } while ((status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
  858. if (i == EHC_MAX_WAIT) {
  859. DCMN_ERR(CE_WARN, "ehc_read_pcf8591(): read of S1 failed");
  860. return (EHC_FAILURE);
  861. }
  862. if (status & EHC_S1_BER) {
  863. DCMN2_ERR(CE_WARN, "ehc_read_pcf8591(): Bus error");
  864. ehc_init_pcf8584(ehcp);
  865. return (EHC_FAILURE);
  866. }
  867. if (status & EHC_S1_LAB) {
  868. DCMN2_ERR(CE_WARN, "ehc_read_pcf8591(): Lost Arbitration");
  869. ehc_init_pcf8584(ehcp);
  870. return (EHC_FAILURE);
  871. }
  872. if (status & EHC_S1_LRB) {
  873. DCMN_ERR(CE_WARN, "ehc_read_pcf8591(): No slave ACK");
  874. /*
  875. * Send the stop condition.
  876. */
  877. ehc_stop_pcf8584(ehcp);
  878. /*
  879. * Read the last byte - discard it.
  880. */
  881. discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
  882. #ifdef lint
  883. discard = discard;
  884. #endif
  885. return (EHC_FAILURE);
  886. }
  887. /*
  888. * Discard first read as per PCF8584 master receiver protocol.
  889. * This is normally done in the ehc_start_pcf8584() routine.
  890. */
  891. if ((status = ehc_read_pcf8584(ehcp, &discard)) != EHC_SUCCESS) {
  892. return (EHC_FAILURE);
  893. }
  894. /* Discard second read as per PCF8591 protocol */
  895. if ((status = ehc_read_pcf8584(ehcp, &discard)) != EHC_SUCCESS) {
  896. return (EHC_FAILURE);
  897. }
  898. for (i = 0; i < size - 1; i++) {
  899. if ((status = ehc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
  900. return (EHC_FAILURE);
  901. }
  902. }
  903. if (ehc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
  904. return (EHC_FAILURE);
  905. }
  906. return (EHC_SUCCESS);
  907. }
  908. /*
  909. * Write to the PCF8591 chip.
  910. * byteaddress = chip type base address | chip offset address.
  911. */
  912. int
  913. ehc_write_pcf8591(struct ehc_envcunit *ehcp, int byteaddress, int channel,
  914. int autoinc, int amode, int aenable, uint8_t *buf, int size)
  915. {
  916. int i, status;
  917. register uint8_t control;
  918. ASSERT((byteaddress & 0x1) == 0);
  919. ASSERT(MUTEX_HELD(&ehcp->umutex));
  920. control = ((aenable << 6) | (amode << 4) | (autoinc << 2) | channel);
  921. status = ehc_start_pcf8584(ehcp, byteaddress);
  922. if (status != EHC_SUCCESS) {
  923. if (status == EHC_NO_SLAVE_ACK) {
  924. /*
  925. * Send the "stop" condition.
  926. */
  927. ehc_stop_pcf8584(ehcp);
  928. }
  929. return (EHC_FAILURE);
  930. }
  931. if ((status = ehc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) {
  932. if (status == EHC_NO_SLAVE_ACK)
  933. ehc_stop_pcf8584(ehcp);
  934. return (EHC_FAILURE);
  935. }
  936. for (i = 0; i < size; i++) {
  937. status = ehc_write_pcf8584(ehcp, buf[i]);
  938. if (status != EHC_SUCCESS) {
  939. if (status == EHC_NO_SLAVE_ACK)
  940. ehc_stop_pcf8584(ehcp);
  941. return (EHC_FAILURE);
  942. }
  943. }
  944. ehc_stop_pcf8584(ehcp);
  945. return (EHC_SUCCESS);
  946. }