2014-08-11 09:27:22 +00:00
|
|
|
/*
|
|
|
|
* SD/MMC Greybus driver.
|
|
|
|
*
|
|
|
|
* Copyright 2014 Google Inc.
|
|
|
|
*
|
|
|
|
* Released under the GPLv2 only.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/mmc/host.h>
|
2014-10-02 02:54:11 +00:00
|
|
|
|
2014-08-11 09:27:22 +00:00
|
|
|
#include "greybus.h"
|
|
|
|
|
2014-08-30 23:20:22 +00:00
|
|
|
struct gb_sdio_host {
|
2014-10-28 02:17:09 +00:00
|
|
|
struct gb_connection *connection;
|
2014-08-11 09:27:22 +00:00
|
|
|
struct mmc_host *mmc;
|
|
|
|
struct mmc_request *mrq;
|
|
|
|
// FIXME - some lock?
|
|
|
|
};
|
|
|
|
|
|
|
|
static void gb_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|
|
|
{
|
|
|
|
// FIXME - do something here...
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gb_sd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|
|
|
{
|
|
|
|
// FIXME - do something here...
|
|
|
|
}
|
|
|
|
|
|
|
|
static int gb_sd_get_ro(struct mmc_host *mmc)
|
|
|
|
{
|
|
|
|
// FIXME - do something here...
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct mmc_host_ops gb_sd_ops = {
|
|
|
|
.request = gb_sd_request,
|
|
|
|
.set_ios = gb_sd_set_ios,
|
|
|
|
.get_ro = gb_sd_get_ro,
|
|
|
|
};
|
|
|
|
|
2014-10-28 02:17:09 +00:00
|
|
|
static int gb_sdio_connection_init(struct gb_connection *connection)
|
2014-08-11 09:27:22 +00:00
|
|
|
{
|
|
|
|
struct mmc_host *mmc;
|
2014-08-30 23:20:22 +00:00
|
|
|
struct gb_sdio_host *host;
|
2014-08-11 09:27:22 +00:00
|
|
|
|
2014-11-19 11:54:58 +00:00
|
|
|
mmc = mmc_alloc_host(sizeof(*host), &connection->dev);
|
2014-08-11 09:27:22 +00:00
|
|
|
if (!mmc)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
host = mmc_priv(mmc);
|
|
|
|
host->mmc = mmc;
|
|
|
|
|
|
|
|
mmc->ops = &gb_sd_ops;
|
|
|
|
// FIXME - set up size limits we can handle.
|
2014-10-28 02:17:09 +00:00
|
|
|
// FIXME - register the host controller.
|
2014-08-11 09:27:22 +00:00
|
|
|
|
2014-10-28 02:17:09 +00:00
|
|
|
host->connection = connection;
|
|
|
|
connection->private = host;
|
2014-08-11 09:27:22 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-10-28 02:17:09 +00:00
|
|
|
static void gb_sdio_connection_exit(struct gb_connection *connection)
|
2014-08-11 09:27:22 +00:00
|
|
|
{
|
|
|
|
struct mmc_host *mmc;
|
2014-08-30 23:20:22 +00:00
|
|
|
struct gb_sdio_host *host;
|
2014-08-11 09:27:22 +00:00
|
|
|
|
2014-10-28 02:17:09 +00:00
|
|
|
host = connection->private;
|
2014-10-16 11:35:24 +00:00
|
|
|
if (!host)
|
|
|
|
return;
|
2014-08-11 09:27:22 +00:00
|
|
|
|
2014-10-16 11:35:24 +00:00
|
|
|
mmc = host->mmc;
|
2014-08-11 09:27:22 +00:00
|
|
|
mmc_remove_host(mmc);
|
|
|
|
mmc_free_host(mmc);
|
2014-10-28 02:17:09 +00:00
|
|
|
connection->private = NULL;
|
2014-08-11 09:27:22 +00:00
|
|
|
}
|
|
|
|
|
2014-11-05 22:12:53 +00:00
|
|
|
static struct gb_protocol sdio_protocol = {
|
|
|
|
.id = GREYBUS_PROTOCOL_SDIO,
|
|
|
|
.major = 0,
|
|
|
|
.minor = 1,
|
2014-11-05 22:12:54 +00:00
|
|
|
.connection_init = gb_sdio_connection_init,
|
|
|
|
.connection_exit = gb_sdio_connection_exit,
|
2014-11-05 22:12:55 +00:00
|
|
|
.request_recv = NULL, /* no incoming requests */
|
2014-11-05 22:12:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
bool gb_sdio_protocol_init(void)
|
|
|
|
{
|
|
|
|
return gb_protocol_register(&sdio_protocol);
|
|
|
|
}
|
|
|
|
|
|
|
|
void gb_sdio_protocol_exit(void)
|
|
|
|
{
|
|
|
|
gb_protocol_deregister(&sdio_protocol);
|
|
|
|
}
|