/*
    zgpio.h - GPIO library
    Copyright (C) 2018 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#ifndef __ZGPIO_H
#define __ZGPIO_H

#include <glib.h>

#define ZMCP23017_SLAVE 0x20

struct zselect;
struct zgpio;
struct zbus;

enum zgpio_chip_type{
    ZGPIOCHIP_SYSGPIO = 0,
    ZGPIOCHIP_MCP23017 = 1
};

enum zgpio_edge{
    ZGPIO_EDGE_NONE = 0,
    ZGPIO_EDGE_RISING = 1,
    ZGPIO_EDGE_FALLING = 2,
    ZGPIO_EDGE_BOTH = 3
};

struct zgpio{
    struct zgpiochip *chip;
    int nr;
    char *name;
    int unexport_after;
    
    enum zgpio_edge edge;
    void (*handler)(struct zgpio *gpio, int value, void *data);
    void *data;


    // SYSGPIO
    int value_fd;
    struct zselect *zsel;

	// MCP23017
	unsigned char mask;

};  

struct zgpiochip{
    enum zgpio_chip_type type;

	struct zbusdev *dev;
    
    // MCP23017
    struct zgpio *inta;
    unsigned char olat[2];
    unsigned char gpio[2];
    GPtrArray *gpios; // of struct zgpio *
    int mirror; // mirror a/b
    
    void (*freechip)(struct zgpiochip *chip);

    struct zgpio *(*init_nr)(struct zgpiochip *chip, int nr);
    struct zgpio *(*init_name)(struct zgpiochip *chip, const char *name);
    void (*free)(struct zgpio *gpio);
    int (*dir_input)(struct zgpio *gpio);
    int (*dir_output)(struct zgpio *gpio);
    int (*write)(struct zgpio *gpio, int value);
    int (*read)(struct zgpio *gpio);
    int (*set_handler)(struct zgpio *gpio, struct zselect *zsel, enum zgpio_edge edge, 
            void (*handler)(struct zgpio *gpio, int value, void *data), 
            void *data);
};

struct zgpiochip *zgpiochip_init_sysgpio(void);
struct zgpiochip *zgpiochip_init_mcp23017(struct zbusdev *bus, struct zgpio *inta, struct zselect *zsel, int mirror);
void zgpiochip_free(struct zgpiochip *chip);


struct zgpio *zgpio_init_nr(struct zgpiochip *chip, int nr);
struct zgpio *zgpio_init_name(struct zgpiochip *chip, const char *name);
void zgpio_free(struct zgpio *gpio);
int zgpio_dir_input(struct zgpio *gpio);
int zgpio_dir_output(struct zgpio *gpio);
int zgpio_write(struct zgpio *gpio, int value);
int zgpio_read(struct zgpio *gpio);
int zgpio_set_handler(struct zgpio *chip, struct zselect *zsel, enum zgpio_edge edge, 
        void (*handler)(struct zgpio *gpio, int value, void *data), 
        void *data);

#endif
