Ejemplo n.º 1
0
static int
todds1307_write_rtc(struct rtc_t *rtc)
{
    ds1307_state_t	*statep = NULL;
    i2c_transfer_t	*i2c_tp = NULL;
    int i2c_cmd_status = I2C_SUCCESS;


    if (!todds1307_attach_done) {
        return (todds1307_prom_setdate(rtc));
    }

    statep = ddi_get_soft_state(ds1307_statep, instance);
    if (statep == NULL) {
        return (DDI_FAILURE);
    }

    if ((i2c_cmd_status = i2c_transfer_alloc(statep->ds1307_i2c_hdl,
                          &i2c_tp, 8, 0, I2C_SLEEP)) != I2C_SUCCESS) {
        return (i2c_cmd_status);
    }

    i2c_tp->i2c_version = I2C_XFER_REV;
    i2c_tp->i2c_flags = I2C_WR;
    i2c_tp->i2c_wbuf[0] = (uchar_t)0x00;
    i2c_tp->i2c_wbuf[1] = rtc->rtc_sec;
    i2c_tp->i2c_wbuf[2] = rtc->rtc_min;
    i2c_tp->i2c_wbuf[3] = rtc->rtc_hrs;
    i2c_tp->i2c_wbuf[4] = rtc->rtc_dow;
    i2c_tp->i2c_wbuf[5] = rtc->rtc_dom;
    i2c_tp->i2c_wbuf[6] = rtc->rtc_mon;
    i2c_tp->i2c_wbuf[7] = rtc->rtc_year;
    i2c_tp->i2c_wlen = 8;

    if ((i2c_cmd_status = i2c_transfer(statep->ds1307_i2c_hdl,
                                       i2c_tp)) != I2C_SUCCESS) {
        (void) i2c_transfer_free(statep->ds1307_i2c_hdl, i2c_tp);
        /* delay(drv_usectohz(I2C_DELAY)); */
        drv_usecwait(I2C_DELAY);
        return (i2c_cmd_status);
    }

    tod_read[0] = -1;  /* invalidate saved data from read routine */

    (void) i2c_transfer_free(statep->ds1307_i2c_hdl, i2c_tp);

    return (i2c_cmd_status);
}
Ejemplo n.º 2
0
static void
pca9556_detach(dev_info_t *dip)
{
	pca9556_unit_t *pcap;
	int 		instance = ddi_get_instance(dip);

	pcap = ddi_get_soft_state(pca9556_soft_statep, instance);

	if ((pcap->pca9556_flags & PCA9556_REGFLAG) == PCA9556_REGFLAG) {
		i2c_client_unregister(pcap->pca9556_hdl);
	}
	if ((pcap->pca9556_flags & PCA9556_TBUFFLAG) == PCA9556_TBUFFLAG) {
		i2c_transfer_free(pcap->pca9556_hdl, pcap->pca9556_transfer);
	}
	if ((pcap->pca9556_flags & PCA9556_MINORFLAG) == PCA9556_MINORFLAG) {
		ddi_remove_minor_node(dip, NULL);
	}
	cv_destroy(&pcap->pca9556_cv);
	mutex_destroy(&pcap->pca9556_mutex);
	ddi_soft_state_free(pca9556_soft_statep, instance);

}
Ejemplo n.º 3
0
static int
todds1307_read_rtc(struct rtc_t *rtc)
{
    static	ds1307_state_t	*statep = NULL;
    i2c_transfer_t	*i2c_tp = NULL;
    int i2c_cmd_status = I2C_FAILURE;
    int counter = 4;

    if (!todds1307_attach_done) {
        return (todds1307_prom_getdate(rtc));
    }

    statep = ddi_get_soft_state(ds1307_statep, instance);
    if (statep == NULL) {
        cmn_err(CE_WARN, "todds1307: ddi_get_soft_state failed");
        return (DDI_FAILURE);
    }

    mutex_enter(&todds1307_rd_lock);

    /*
     * Allocate 1 byte for write buffer and 7 bytes for read buffer to
     * to accomodate sec, min, hrs, dayOfWeek, dayOfMonth, year
     */
    if ((i2c_transfer_alloc(statep->ds1307_i2c_hdl, &i2c_tp, 1,
                            7, I2C_SLEEP)) != I2C_SUCCESS) {
        mutex_exit(&todds1307_rd_lock);
        return (DDI_FAILURE);
    }

    do {
        i2c_tp->i2c_version = I2C_XFER_REV;
        i2c_tp->i2c_flags = I2C_WR_RD;
        i2c_tp->i2c_wbuf[0] = (uchar_t)0x00; /* Start from reg 0x00 */
        i2c_tp->i2c_wlen = 1;	/* Write one byte address */
        i2c_tp->i2c_rlen = 7;	/* Read 7 regs */

        if ((i2c_cmd_status = i2c_transfer(statep->ds1307_i2c_hdl,
                                           i2c_tp)) != I2C_SUCCESS) {
            drv_usecwait(I2C_DELAY);
            goto done;
        }
        /* for first read, need to get valid data */
        while (tod_read[0] == -1 && counter > 0) {
            /* move data to static buffer */
            bcopy(i2c_tp->i2c_rbuf, tod_read, 7);

            /* now read again */
            /* Start reading reg from 0x00 */
            i2c_tp->i2c_wbuf[0] = (uchar_t)0x00;
            i2c_tp->i2c_wlen = 1;	/* Write one byte address */
            i2c_tp->i2c_rlen = 7;	/* Read 7 regs */
            if ((i2c_cmd_status = i2c_transfer(statep->ds1307_i2c_hdl,
                                               i2c_tp)) != I2C_SUCCESS) {
                drv_usecwait(I2C_DELAY);
                goto done;
            }
            /* if they are not the same, then read again */
            if (bcmp(tod_read, i2c_tp->i2c_rbuf, 7) != 0) {
                tod_read[0] = -1;
                counter--;
            }
        }

    } while (i2c_tp->i2c_rbuf[0] == 0x59 &&
             /* if seconds register is 0x59 (BCD), add data should match */
             bcmp(&tod_read[1], &i2c_tp->i2c_rbuf[1], 6) != 0 &&
             counter-- > 0);

    if (counter < 0)
        cmn_err(CE_WARN, "i2ctod: TOD Chip failed ??");

    /* move data to static buffer */
    bcopy(i2c_tp->i2c_rbuf, tod_read, 7);


    rtc->rtc_year	= bcd2int(i2c_tp->i2c_rbuf[6]);
    rtc->rtc_mon	= bcd2int(i2c_tp->i2c_rbuf[5]);
    rtc->rtc_dom	= bcd2int(i2c_tp->i2c_rbuf[4]);
    rtc->rtc_dow	= bcd2int(i2c_tp->i2c_rbuf[3]);
    rtc->rtc_hrs	= bcd2int(i2c_tp->i2c_rbuf[2]);
    rtc->rtc_min	= bcd2int(i2c_tp->i2c_rbuf[1]);
    rtc->rtc_sec	= bcd2int(i2c_tp->i2c_rbuf[0]);

done:
    (void) i2c_transfer_free(statep->ds1307_i2c_hdl, i2c_tp);

    mutex_exit(&todds1307_rd_lock);
    return (i2c_cmd_status);
}
Ejemplo n.º 4
0
/*
 * register ds1307 client device with i2c services, and
 * allocate & initialize soft state structure.
 */
static int
todds1307_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
    static ds1307_state_t	*statep = NULL;
    i2c_transfer_t	*i2c_tp = NULL;
    uint8_t tempVal = (uint8_t)0;
    switch (cmd) {

    case DDI_ATTACH:
        break;
    case DDI_RESUME:
        return (DDI_SUCCESS);
    default:
        return (DDI_FAILURE);
    }

    if (instance != -1) {
        return (DDI_FAILURE);
    }

    instance = ddi_get_instance(dip);

    /*
     * Allocate soft state structure
     */
    if (ddi_soft_state_zalloc(ds1307_statep, instance) != DDI_SUCCESS) {
        return (DDI_FAILURE);
    }

    statep = ddi_get_soft_state(ds1307_statep, instance);
    if (statep == NULL) {
        return (DDI_FAILURE);
    }

    statep->dip = dip;

    if (i2c_client_register(dip, &statep->ds1307_i2c_hdl) != I2C_SUCCESS) {
        ddi_soft_state_free(ds1307_statep, instance);
        delay(drv_usectohz(I2C_DELAY));
        return (DDI_FAILURE);
    }

    /* check and initialize the oscillator */

    (void) i2c_transfer_alloc(statep->ds1307_i2c_hdl,
                              &i2c_tp, 1, 1, I2C_SLEEP);
    i2c_tp->i2c_version = I2C_XFER_REV;
    i2c_tp->i2c_flags = I2C_WR_RD;
    i2c_tp->i2c_wbuf[0] = (uchar_t)0x00; /* Read 00h */
    i2c_tp->i2c_wlen = 1;
    i2c_tp->i2c_rlen = 1;

    if ((i2c_transfer(statep->ds1307_i2c_hdl, i2c_tp)) != I2C_SUCCESS) {
        (void) i2c_transfer_free(statep->ds1307_i2c_hdl, i2c_tp);
        ddi_soft_state_free(ds1307_statep, instance);
        delay(drv_usectohz(I2C_DELAY));
        return (DDI_FAILURE);
    }

    tempVal = i2c_tp->i2c_rbuf[0];

    (void) i2c_transfer_free(statep->ds1307_i2c_hdl, i2c_tp);

    if (tempVal & 0x80) {			 /* check Oscillator */
        (void) i2c_transfer_alloc(statep->ds1307_i2c_hdl, &i2c_tp,
                                  2, 1, I2C_SLEEP);
        i2c_tp->i2c_version = I2C_XFER_REV;
        i2c_tp->i2c_flags = I2C_WR;
        i2c_tp->i2c_wbuf[0] = 0x00;
        i2c_tp->i2c_wbuf[1] =
            (uchar_t)(i2c_tp->i2c_rbuf[0]& 0x7f);
        i2c_tp->i2c_wlen = 2;
        /* Enable oscillator */
        if ((i2c_transfer(statep->ds1307_i2c_hdl, i2c_tp))
                != I2C_SUCCESS) {
            (void) i2c_transfer_free(statep->ds1307_i2c_hdl,
                                     i2c_tp);
            ddi_soft_state_free(ds1307_statep, instance);
            return (DDI_FAILURE);
        }
        (void) i2c_transfer_free(statep->ds1307_i2c_hdl, i2c_tp);
    }

    /*
     * Create a periodical handler to read TOD.
     */
    ASSERT(statep->cycid == NULL);
    statep->cycid = ddi_periodic_add(todds1307_cyclic, &soft_rtc,
                                     i2c_cyclic_timeout, DDI_IPL_1);

    statep->state = TOD_ATTACHED;
    todds1307_attach_done = 1;
    ddi_report_dev(dip);

    return (DDI_SUCCESS);
}