/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* SD card initialization support.
*/
/*
* Local Prototypes.
*/
sda_rtype_t, uint32_t *);
sda_rtype_t, uint32_t *);
uint8_t *);
/*
* Implementation.
*/
{
return (errno);
}
{
return (errno);
}
{
/*
* TODO: SDIO: We need to initialize the SDIO OCR register using
* the special CMD_IO_SEND_OCR (CMD5) command.
*/
return (SDA_EOK);
}
{
int count;
/*
* Try sending the ACMD41 to query the OCR (Op Cond Register).
*/
/*
* Card failed to respond to query, not an SD card?
* We send GO_IDLE to clear any error status on the
* card.
*/
return (SDA_EOK);
}
/*
* Now we have to send our OCR value, along with the HCS (High
* Capacity Support) bit. The HCS bit is required, to
* activate high capacity cards. We only set the HCS bit if
* the card responded to CMD8 (SEND_IFCOND), indicating that
* it supports the new protocol.
*
* Note that the HCS bit occupies the same location as the CCS bit
* in the response.
*/
return (SDA_ENOTSUP);
}
/* set the HCS bit if its a ver 2.00 card */
}
/* make sure card is powered up */
return (SDA_ENOTSUP);
}
/* Now check the busy bit */
if (r3 & OCR_POWER_UP) {
} else {
}
return (0);
}
drv_usecwait(10000);
}
return (SDA_ETIME);
}
{
int count;
/*
* If the card has already been identified as an SD card, then
* cannot also be an MMC card, so don't probe it as such.
*/
return (SDA_EOK);
}
/*
* Try sending the CMD1 to query the OCR.
*/
/*
* Card failed to respond to query, not an MMC card?
* We send GO_IDLE to clear any error status on the
* card.
*/
return (SDA_EOK);
}
return (SDA_ENOTSUP);
}
/* make sure card is powered up */
return (SDA_ENOTSUP);
}
/* Now check the busy bit */
if (r3 & OCR_POWER_UP) {
return (SDA_EOK);
}
drv_usecwait(10000);
}
return (SDA_ETIME);
}
{
int rv;
/*
*/
/*
* Apply initial power to the slot.
*/
return (rv);
}
/*
* First enable the clock, but only at 400 kHz. All cards are
* supposed to be able to operate between this speed and 100
* kHz, and all hosts must be able to pick a speed between 100
* kHz and 400 kHz.
*
* Once we know what the device can support, then we speed up.
*/
goto done;
}
/* message will already have been logged */
goto done;
}
rv = SDA_ENOTSUP;
goto done;
}
/*
* Memory cards need to obtain their CID before getting their RCA.
* This is a requirement for the state transitions... they go thru
* the ident state, unlike SDIO cards.
*/
goto done;
}
}
goto done;
}
/*
* Figure out card supported bus width and speed.
*
* TODO: SDIO: For IO cards, we have to check what speed the card
* supports by looking in the CCCR_CAPAB register. (SDIO cards
* can go low-speed only, full-speed, or high-speed.)
*/
/*
* We need to obtain the CSD.
*/
if (rv != 0) {
goto done;
}
/*
* Calculate the maxclock.
*/
}
}
}
/*
* Now select the card.
*/
goto done;
}
goto done;
}
/*
* Lets go to 4-bit bus mode, if possible.
*/
goto done;
}
goto done;
}
/* note if a card is writable */
(val == 0)) {
}
done:
return (rv);
}
{
int rv;
return (SDA_EOK);
}
/*
* All memory cards support block sizes of 512. Full stop.
*/
}
return (rv);
}
void
{
int rv;
/*
* Note that at no time is a failure programming the clock
* itself necessarily a fatal error. Although if the clock
* wasn't programmed, other things will probably not work during
* initialization.
*/
/* XXX: FMA fail the slot */
return;
}
/*
* For now, just wait 10msec for clocks to stabilize to the
* card. (Is this really necessary?)
*/
}
{
int rv;
/*
* Spec says we should command the card first.
*/
return (rv);
}
return (SDA_EOK);
}
/*
* TODO: SDIO: SDIO cards set the CCCR_BUS_WIDTH
* and CCCR_CD_DISABLE bits here.
*/
/*
* If we're going to use all 4 pins, we really need to disconnect
* the card pullup resistor. A consquence of this, is that hosts
* which use that resistor for detection must not claim to support
* 4-bit bus mode. This is a limitation of our implementation.
*/
"Unable disconnect DAT3 resistor on card (%d, %x)",
/* non-fatal error, muddle on */
return (SDA_EOK);
}
/* non-fatal error, muddle on */
return (SDA_EOK);
}
/*
* This is bad news. We've already asked for the card to
* to use 4-bit mode, but the host is not complying. It
* shouldn't ever happen, so we just error out.
*/
}
return (rv);
}
{
int rv;
int tries;
/*
* Try SEND_IF_COND. Note that this assumes that the host is
* supplying 2.7 - 3.6 voltage range. The standard is not
* defined for any other ranges.
*/
/* we try this a few times, just to be sure */
return (rv);
}
break;
}
}
return (SDA_ENOTSUP);
} else {
/* SDHC compliant */
}
return (SDA_EOK);
}
{
int rv;
int tries;
/*
* Program the RCA. Note that MMC has a different mechanism
* for this.
*/
/*
* For MMC, we push the RCA to the MMC. We
* arbitrarily start at 0x100, and add from
* there.
*/
} else {
/*
* For SDcard, we are basically asking the
* card to propose a value. It *may* propose
* a value of zero, in which case we will have
* to ask again.
*/
}
return (SDA_EOK);
}
}
}
{
/*
* The spec says we should leave unselected groups set to 0xf,
* to prevent inadvertent changes.
*/
return (errno);
}
{
return (SDA_EOK);
}
return (SDA_EOK);
}
return (SDA_EOK);
}
/* these are big-endian bits, bit 401 */
return (SDA_EOK);
}
return (SDA_EOK);
}
/* now program the card */
} else {
/* the card should now support 50 MHz */
}
return (rv);
}