After reading Design Patterns for Embedded Systems in C I changed the way I implement device drivers. The book suggests that a typical device driver header file has this implementation.
/* Encapsulated device handle using 'opaque' pointer */
typedef struct device device_t;
/* Allocated dynamically */
device_t*   device_create( i2c_t* bus, const uint8_t address );
void        device_destroy( device_t* me );    
int         device_initialize( device_t* me );
int         device_deinitialize( device_t* me );
int         device_isAvailable( device_t* me );
int         device_configure( device_t* me, const device_config_t config );
Yes I know C is not object-oriented but I like how clean the code smells. I changed the code a little bit. I sacrificed device handle encapsulation in order to be able to allocate it statically.
/* Public(no ecapsulation) device handle */
typedef struct device
{
    int public_member1;
    int public_member2;
} device_t;
/* Allocated statically */
device_t    device_create( i2c_t* bus, const uint8_t address );
int         device_initialize( device_t* me );
int         device_deinitialize( device_t* me );
int         device_isAvailable( device_t* me );
int         device_configure( device_t* me, const device_config_t config );
I would rather not allocate dynamically if possible since I fear memory fragmentation but I will if it is a good design desicion. Since my project is embedded and my target an cortex-m0 I wanted to know if I could use static allocation and ecapsulation together..
Update:
I give two different implementations of device_create for the above code
Dynamically:
device_t* device_create( i2c_t* bus, const uint8_t address )
{
    /* Check input */
    if( bus == NULL )
    {
        return NULL;
    }
    /* Create handle */
    device_t* aux = (device_t*)malloc( sizeof( device_t ) );
    if( aux == NULL )
    {
        return NULL;
    }
    /* Initialize handle */
    init( aux, bus, address );
    /* Return handle */     
    return aux;
}
Statically:
device_t device_create( i2c_t* bus, const uint8_t address )
{
    /* Check input */
    if( bus == NULL )
    {
        return NULL;
    }
    /* Create handle */
    device_t aux;
    /* Initialize handle */
    init( &aux, bus, address );
    /* Return handle */     
    return aux;
}