1/** 2 * \file 3 * \brief MMCHS Driver main routine. 4 */ 5/* 6 * Copyright (c) 2013, ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 12 */ 13 14#include <stdlib.h> 15#include <stdio.h> 16#include <string.h> 17#include <assert.h> 18 19#include <barrelfish/barrelfish.h> 20#include <barrelfish/nameservice_client.h> 21#include <driverkit/driverkit.h> 22 23#include <if/cm2_defs.h> 24 25#include "twl6030.h" 26 27static void cm2_connected(void *st, errval_t err, struct cm2_binding *b) { 28 TWL_DEBUG("Connected to cm2 driver\n"); 29 assert(err_is_ok(err)); 30 struct twl6030_driver_state* dst = (struct twl6030_driver_state*) st; 31 dst->cm2_binding = b; 32 cm2_rpc_client_init(b); 33} 34 35/** 36 * Driver initialization function. This function is called by the driver domain 37 * (see also 'create_handler' in ddomain_service.c). 38 * Typically through a request from the device manager. 39 * 40 * The init function is supposed to set `dev` to the exported service iref. 41 * The init function may use `bfi->dstate` to store additional state about the device. 42 * 43 * \param[in] bfi The instance of this driver. 44 * \param[in] name The name of this driver instance. 45 * \param[in] flags Additional flags (The exact flags supported is device/driver specific). 46 * \param[in] c Capabilities (for registers etc.) as provided by the device manager. 47 * The exact layout of the `c` is device specific. 48 * \param[out] dev The service iref over which the device can be contacted. 49 * 50 * \retval SYS_ERR_OK Device initialized successfully. 51 * \retval LIB_ERR_MALLOC_FAIL Unable to allocate memory for the driver. 52 */ 53 54static errval_t init(struct bfdriver_instance *bfi, uint64_t flags, iref_t *dev) { 55 TWL_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name); 56 57 bfi->dstate = malloc(sizeof(struct twl6030_driver_state)); 58 if (bfi->dstate == NULL) { 59 return LIB_ERR_MALLOC_FAIL; 60 } 61 62 assert(bfi->dstate != NULL); 63 64 struct twl6030_driver_state* st = (struct twl6030_driver_state*) bfi->dstate; 65 st->cap = bfi->caps[0]; 66 67 // Connect to the cm2 driver 68 iref_t cm2_iref; 69 errval_t err = nameservice_lookup("cm2", &cm2_iref); 70 if (err_is_fail(err)) { 71 USER_PANIC_ERR(err, "finding cm2 service failed."); 72 } 73 74 err = cm2_bind(cm2_iref, cm2_connected, st, get_default_waitset(), IDC_EXPORT_FLAG_NO_NOTIFY); 75 if (err_is_fail(err)) { 76 USER_PANIC_ERR(err, "call failed."); 77 } 78 79 while(st->cm2_binding == NULL) { 80 messages_wait_and_handle_next(); 81 } 82 assert(st->cm2_binding != NULL); 83 84 85 ti_twl6030_init(st); 86 twl6030_init_service(st, dev); 87 88 return SYS_ERR_OK; 89} 90 91/** 92 * Instructs driver to attach to the device. 93 * This function is only called if the driver has previously detached 94 * from the device (see also detach). 95 * 96 * \note After detachment the driver can not assume anything about the 97 * configuration of the device. 98 * 99 * \param[in] bfi The instance of this driver. 100 * \retval SYS_ERR_OK Device initialized successfully. 101 */ 102static errval_t attach(struct bfdriver_instance* bfi) { 103 TWL_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name); 104 105 return SYS_ERR_OK; 106} 107 108/** 109 * Instructs driver to detach from the device. 110 * The driver must yield any control over to the device after this function returns. 111 * The device may be left in any state. 112 * 113 * \param[in] bfi The instance of this driver. 114 * \retval SYS_ERR_OK Device initialized successfully. 115 */ 116static errval_t detach(struct bfdriver_instance* bfi) { 117 TWL_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name); 118 119 return SYS_ERR_OK; 120} 121 122/** 123 * Instructs the driver to go in a particular sleep state. 124 * Supported states are platform/device specific. 125 * 126 * \param[in] bfi The instance of this driver. 127 * \retval SYS_ERR_OK Device initialized successfully. 128 */ 129static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) { 130 TWL_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name); 131 132 struct twl6030_driver_state* uds = bfi->dstate; 133 uds->level = level; 134 135 return SYS_ERR_OK; 136} 137 138/** 139 * Destroys this driver instance. The driver will yield any 140 * control over the device and free any state allocated. 141 * 142 * \param[in] bfi The instance of this driver. 143 * \retval SYS_ERR_OK Device initialized successfully. 144 */ 145static errval_t destroy(struct bfdriver_instance* bfi) { 146 TWL_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name); 147 struct twl6030_driver_state* uds = bfi->dstate; 148 free(uds); 149 bfi->dstate = NULL; 150 151 // XXX: Tear-down the service 152 bfi->device = 0x0; 153 154 return SYS_ERR_OK; 155} 156 157static errval_t get_ep(struct bfdriver_instance* bfi, bool lmp, struct capref* ret_cap) 158{ 159 USER_PANIC("NIY \n"); 160 return SYS_ERR_OK; 161} 162 163/** 164 * Registers the driver module with the system. 165 * 166 * To link this particular module in your driver domain, 167 * add it to the addModules list in the Hakefile. 168 */ 169DEFINE_MODULE(twl6030, init, attach, detach, set_sleep_level, destroy, get_ep); 170