/* $NetBSD: auvitekvar.h,v 1.10 2022/03/13 12:49:36 riastradh Exp $ */

/*-
* Copyright (c) 2010 Jared D. McNeill <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef _AUVITEKVAR_H
#define _AUVITEKVAR_H

#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/kthread.h>

#include <dev/dtv/dtvif.h>

#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
#include <dev/i2c/i2cvar.h>

#include <dev/i2c/au8522var.h>
#include <dev/i2c/xc5kvar.h>
#include <dev/i2c/xc5kreg.h>

struct auvitek_softc;

enum auvitek_board {
       AUVITEK_BOARD_HVR_850,
       AUVITEK_BOARD_HVR_950Q,
};

#define AUVITEK_NISOC_XFERS     16
#define AUVITEK_NBULK_XFERS     1
#define AUVITEK_XFER_ALTNO      5
#define AUVITEK_BULK_BUFLEN     58658   /* BDA driver uses the same */

struct auvitek_isoc {
       struct auvitek_xfer     *i_ax;
       struct usbd_xfer        *i_xfer;
       uint8_t                 *i_buf;
       uint16_t                *i_frlengths;
};

struct auvitek_videobuf {
       uint8_t                 av_buf[720*480*2];
       uint32_t                av_el, av_eb;
       uint32_t                av_ol, av_ob;
       uint32_t                av_stride;
};

struct auvitek_xfer {
       struct auvitek_softc    *ax_sc;
       int                     ax_endpt;
       uint16_t                ax_maxpktlen;
       struct usbd_pipe *      ax_pipe;
       struct auvitek_isoc     ax_i[AUVITEK_NISOC_XFERS];
       uint32_t                ax_nframes;
       uint32_t                ax_uframe_len;
       uint8_t                 ax_frinfo;
       int                     ax_frno;
       struct auvitek_videobuf ax_av;
};

struct auvitek_bulk_xfer {
       struct auvitek_softc    *bx_sc;
       struct usbd_xfer        *bx_xfer;
       uint8_t                 *bx_buffer;
};

struct auvitek_bulk {
       struct auvitek_softc    *ab_sc;
       int                     ab_endpt;
       struct usbd_pipe        *ab_pipe;
       struct auvitek_bulk_xfer ab_bx[AUVITEK_NBULK_XFERS];
       bool                    ab_running;
};

struct auvitek_softc {
       device_t                sc_dev;
       device_t                sc_videodev, sc_dtvdev, sc_audiodev, sc_i2cdev;
       struct i2c_controller   sc_i2c;
       kmutex_t                sc_i2c_lock;
       bool                    sc_i2c_attached;

       struct usbd_device     *sc_udev;
       int                     sc_uport;
       struct usbd_interface  *sc_isoc_iface;
       struct usbd_interface  *sc_bulk_iface;

       char                    sc_running;
       char                    sc_dying;

       enum auvitek_board      sc_board;
       const char              *sc_descr;
       uint8_t                 sc_i2c_clkdiv;

       struct au8522           *sc_au8522;
       struct xc5k             *sc_xc5k;
       kmutex_t                sc_subdev_lock;

       unsigned int            sc_ainput, sc_vinput;
       uint32_t                sc_curfreq;
       void                    (*sc_dtvsubmitcb)(void *,
                                   const struct dtv_payload *);
       void                    *sc_dtvsubmitarg;

       struct auvitek_xfer     sc_ax;
       struct auvitek_bulk     sc_ab;

       char                    sc_businfo[32];
};

/* auvitek.c */
uint8_t auvitek_read_1(struct auvitek_softc *, uint16_t);
void    auvitek_write_1(struct auvitek_softc *, uint16_t, uint8_t);
void    auvitek_attach_tuner(device_t);

/* auvitek_audio.c */
int     auvitek_audio_attach(struct auvitek_softc *);
int     auvitek_audio_detach(struct auvitek_softc *, int);
void    auvitek_audio_childdet(struct auvitek_softc *, device_t);

/* auvitek_board.c */
void    auvitek_board_init(struct auvitek_softc *);
int     auvitek_board_tuner_reset(void *);
unsigned int auvitek_board_get_if_frequency(struct auvitek_softc *);

/* auvitek_i2c.c */
int     auvitek_i2c_attach(struct auvitek_softc *);
int     auvitek_i2c_detach(struct auvitek_softc *, int);
void    auvitek_i2c_rescan(struct auvitek_softc *, const char *, const int *);
void    auvitek_i2c_childdet(struct auvitek_softc *, device_t);

/* auvitek_video.c */
int     auvitek_video_attach(struct auvitek_softc *);
int     auvitek_video_detach(struct auvitek_softc *, int);
void    auvitek_video_rescan(struct auvitek_softc *, const char *, const int *);
void    auvitek_video_childdet(struct auvitek_softc *, device_t);

/* auvitek_dtv.c */
int     auvitek_dtv_attach(struct auvitek_softc *);
int     auvitek_dtv_detach(struct auvitek_softc *, int);
void    auvitek_dtv_rescan(struct auvitek_softc *, const char *, const int *);
void    auvitek_dtv_childdet(struct auvitek_softc *, device_t);

#endif /* !_AUVITEKVAR_H */