linux/drivers/staging/media/zoran/zr36060.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Zoran ZR36060 basic configuration functions
   4 *
   5 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
   6 */
   7
   8#define ZR060_VERSION "v0.7"
   9
  10#include <linux/module.h>
  11#include <linux/init.h>
  12#include <linux/slab.h>
  13#include <linux/delay.h>
  14
  15#include <linux/types.h>
  16#include <linux/wait.h>
  17
  18/* I/O commands, error codes */
  19#include <linux/io.h>
  20
  21/* headerfile of this module */
  22#include "zr36060.h"
  23
  24/* codec io API */
  25#include "videocodec.h"
  26
  27/* it doesn't make sense to have more than 20 or so, just to prevent some unwanted loops */
  28#define MAX_CODECS 20
  29
  30/* amount of chips attached via this driver */
  31static int zr36060_codecs;
  32
  33static bool low_bitrate;
  34module_param(low_bitrate, bool, 0);
  35MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
  36
  37/* debugging is available via module parameter */
  38static int debug;
  39module_param(debug, int, 0);
  40MODULE_PARM_DESC(debug, "Debug level (0-4)");
  41
  42#define dprintk(num, format, args...) \
  43        do { \
  44                if (debug >= num) \
  45                        printk(format, ##args); \
  46        } while (0)
  47
  48/* =========================================================================
  49 * Local hardware I/O functions:
  50 * read/write via codec layer (registers are located in the master device)
  51 * =========================================================================
  52 */
  53
  54static u8 zr36060_read(struct zr36060 *ptr, u16 reg)
  55{
  56        u8 value = 0;
  57
  58        // just in case something is wrong...
  59        if (ptr->codec->master_data->readreg)
  60                value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xff;
  61        else
  62                pr_err("%s: invalid I/O setup, nothing read!\n", ptr->name);
  63
  64        return value;
  65}
  66
  67static void zr36060_write(struct zr36060 *ptr, u16 reg, u8 value)
  68{
  69        dprintk(4, "0x%02x @0x%04x\n", value, reg);
  70
  71        // just in case something is wrong...
  72        if (ptr->codec->master_data->writereg)
  73                ptr->codec->master_data->writereg(ptr->codec, reg, value);
  74        else
  75                pr_err("%s: invalid I/O setup, nothing written!\n", ptr->name);
  76}
  77
  78/* =========================================================================
  79 * Local helper function:
  80 * status read
  81 * =========================================================================
  82 */
  83
  84/* status is kept in datastructure */
  85static u8 zr36060_read_status(struct zr36060 *ptr)
  86{
  87        ptr->status = zr36060_read(ptr, ZR060_CFSR);
  88
  89        zr36060_read(ptr, 0);
  90        return ptr->status;
  91}
  92
  93/* scale factor is kept in datastructure */
  94static u16 zr36060_read_scalefactor(struct zr36060 *ptr)
  95{
  96        ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
  97                         (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
  98
  99        /* leave 0 selected for an eventually GO from master */
 100        zr36060_read(ptr, 0);
 101        return ptr->scalefact;
 102}
 103
 104/* wait if codec is ready to proceed (end of processing) or time is over */
 105static void zr36060_wait_end(struct zr36060 *ptr)
 106{
 107        int i = 0;
 108
 109        while (zr36060_read_status(ptr) & ZR060_CFSR_BUSY) {
 110                udelay(1);
 111                if (i++ > 200000) {     // 200ms, there is for sure something wrong!!!
 112                        dprintk(1,
 113                                "%s: timeout at wait_end (last status: 0x%02x)\n",
 114                                ptr->name, ptr->status);
 115                        break;
 116                }
 117        }
 118}
 119
 120/* Basic test of "connectivity", writes/reads to/from memory the SOF marker */
 121static int zr36060_basic_test(struct zr36060 *ptr)
 122{
 123        if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) &&
 124            (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) {
 125                pr_err("%s: attach failed, can't connect to jpeg processor!\n", ptr->name);
 126                return -ENXIO;
 127        }
 128
 129        zr36060_wait_end(ptr);
 130        if (ptr->status & ZR060_CFSR_BUSY) {
 131                pr_err("%s: attach failed, jpeg processor failed (end flag)!\n", ptr->name);
 132                return -EBUSY;
 133        }
 134
 135        return 0;               /* looks good! */
 136}
 137
 138/* simple loop for pushing the init datasets */
 139static int zr36060_pushit(struct zr36060 *ptr, u16 startreg, u16 len, const char *data)
 140{
 141        int i = 0;
 142
 143        dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
 144                startreg, len);
 145        while (i < len)
 146                zr36060_write(ptr, startreg++, data[i++]);
 147
 148        return i;
 149}
 150
 151/* =========================================================================
 152 * Basic datasets:
 153 * jpeg baseline setup data (you find it on lots places in internet, or just
 154 * extract it from any regular .jpg image...)
 155 *
 156 * Could be variable, but until it's not needed it they are just fixed to save
 157 * memory. Otherwise expand zr36060 structure with arrays, push the values to
 158 * it and initialize from there, as e.g. the linux zr36057/60 driver does it.
 159 * =========================================================================
 160 */
 161static const char zr36060_dqt[0x86] = {
 162        0xff, 0xdb,             //Marker: DQT
 163        0x00, 0x84,             //Length: 2*65+2
 164        0x00,                   //Pq,Tq first table
 165        0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
 166        0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
 167        0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
 168        0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
 169        0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
 170        0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
 171        0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
 172        0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
 173        0x01,                   //Pq,Tq second table
 174        0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
 175        0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
 176        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
 177        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
 178        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
 179        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
 180        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
 181        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
 182};
 183
 184static const char zr36060_dht[0x1a4] = {
 185        0xff, 0xc4,             //Marker: DHT
 186        0x01, 0xa2,             //Length: 2*AC, 2*DC
 187        0x00,                   //DC first table
 188        0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
 189        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
 190        0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
 191        0x01,                   //DC second table
 192        0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 193        0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
 194        0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
 195        0x10,                   //AC first table
 196        0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
 197        0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
 198        0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
 199        0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
 200        0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
 201        0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
 202        0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
 203        0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
 204        0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
 205        0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
 206        0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
 207        0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
 208        0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
 209        0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
 210        0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
 211        0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
 212        0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
 213        0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
 214        0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
 215        0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
 216        0xF8, 0xF9, 0xFA,
 217        0x11,                   //AC second table
 218        0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
 219        0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
 220        0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
 221        0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
 222        0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
 223        0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
 224        0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
 225        0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
 226        0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
 227        0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
 228        0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
 229        0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
 230        0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
 231        0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
 232        0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
 233        0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
 234        0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
 235        0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
 236        0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
 237        0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
 238        0xF9, 0xFA
 239};
 240
 241/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
 242#define NO_OF_COMPONENTS          0x3   //Y,U,V
 243#define BASELINE_PRECISION        0x8   //MCU size (?)
 244static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };   //table idx's QT
 245static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };   //table idx's DC
 246static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };   //table idx's AC
 247
 248/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
 249static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
 250static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
 251
 252/* SOF (start of frame) segment depends on width, height and sampling ratio of each color component */
 253static int zr36060_set_sof(struct zr36060 *ptr)
 254{
 255        char sof_data[34];      // max. size of register set
 256        int i;
 257
 258        dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
 259                ptr->width, ptr->height, NO_OF_COMPONENTS);
 260        sof_data[0] = 0xff;
 261        sof_data[1] = 0xc0;
 262        sof_data[2] = 0x00;
 263        sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
 264        sof_data[4] = BASELINE_PRECISION;       // only '8' possible with zr36060
 265        sof_data[5] = (ptr->height) >> 8;
 266        sof_data[6] = (ptr->height) & 0xff;
 267        sof_data[7] = (ptr->width) >> 8;
 268        sof_data[8] = (ptr->width) & 0xff;
 269        sof_data[9] = NO_OF_COMPONENTS;
 270        for (i = 0; i < NO_OF_COMPONENTS; i++) {
 271                sof_data[10 + (i * 3)] = i;     // index identifier
 272                sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
 273                                         (ptr->v_samp_ratio[i]); // sampling ratios
 274                sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection
 275        }
 276        return zr36060_pushit(ptr, ZR060_SOF_IDX,
 277                              (3 * NO_OF_COMPONENTS) + 10, sof_data);
 278}
 279
 280/* SOS (start of scan) segment depends on the used scan components of each color component */
 281static int zr36060_set_sos(struct zr36060 *ptr)
 282{
 283        char sos_data[16];      // max. size of register set
 284        int i;
 285
 286        dprintk(3, "%s: write SOS\n", ptr->name);
 287        sos_data[0] = 0xff;
 288        sos_data[1] = 0xda;
 289        sos_data[2] = 0x00;
 290        sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
 291        sos_data[4] = NO_OF_COMPONENTS;
 292        for (i = 0; i < NO_OF_COMPONENTS; i++) {
 293                sos_data[5 + (i * 2)] = i;      // index
 294                sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
 295                                        zr36060_ta[i]; // AC/DC tbl.sel.
 296        }
 297        sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00;      // scan start
 298        sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
 299        sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
 300        return zr36060_pushit(ptr, ZR060_SOS_IDX,
 301                              4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
 302                              sos_data);
 303}
 304
 305/* DRI (define restart interval) */
 306static int zr36060_set_dri(struct zr36060 *ptr)
 307{
 308        char dri_data[6];       // max. size of register set
 309
 310        dprintk(3, "%s: write DRI\n", ptr->name);
 311        dri_data[0] = 0xff;
 312        dri_data[1] = 0xdd;
 313        dri_data[2] = 0x00;
 314        dri_data[3] = 0x04;
 315        dri_data[4] = (ptr->dri) >> 8;
 316        dri_data[5] = (ptr->dri) & 0xff;
 317        return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
 318}
 319
 320/* Setup compression/decompression of Zoran's JPEG processor ( see also zoran 36060 manual )
 321 * ... sorry for the spaghetti code ...
 322 */
 323static void zr36060_init(struct zr36060 *ptr)
 324{
 325        int sum = 0;
 326        long bitcnt, tmp;
 327
 328        if (ptr->mode == CODEC_DO_COMPRESSION) {
 329                dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
 330
 331                zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
 332
 333                /* 060 communicates with 067 in master mode */
 334                zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CODE_MSTR);
 335
 336                /* Compression with or without variable scale factor */
 337                /*FIXME: What about ptr->bitrate_ctrl? */
 338                zr36060_write(ptr, ZR060_CMR, ZR060_CMR_COMP | ZR060_CMR_PASS2 | ZR060_CMR_BRB);
 339
 340                /* Must be zero */
 341                zr36060_write(ptr, ZR060_MBZ, 0x00);
 342                zr36060_write(ptr, ZR060_TCR_HI, 0x00);
 343                zr36060_write(ptr, ZR060_TCR_LO, 0x00);
 344
 345                /* Disable all IRQs - no DataErr means autoreset */
 346                zr36060_write(ptr, ZR060_IMR, 0);
 347
 348                /* volume control settings */
 349                zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
 350                zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
 351
 352                zr36060_write(ptr, ZR060_AF_HI, 0xff);
 353                zr36060_write(ptr, ZR060_AF_M, 0xff);
 354                zr36060_write(ptr, ZR060_AF_LO, 0xff);
 355
 356                /* setup the variable jpeg tables */
 357                sum += zr36060_set_sof(ptr);
 358                sum += zr36060_set_sos(ptr);
 359                sum += zr36060_set_dri(ptr);
 360
 361/* setup the fixed jpeg tables - maybe variable, though - (see table init section above) */
 362                sum += zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt), zr36060_dqt);
 363                sum += zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), zr36060_dht);
 364                zr36060_write(ptr, ZR060_APP_IDX, 0xff);
 365                zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
 366                zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
 367                zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
 368                sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60, ptr->app.data) + 4;
 369                zr36060_write(ptr, ZR060_COM_IDX, 0xff);
 370                zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
 371                zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
 372                zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
 373                sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60, ptr->com.data) + 4;
 374
 375                /* setup misc. data for compression (target code sizes) */
 376
 377                /* size of compressed code to reach without header data */
 378                sum = ptr->real_code_vol - sum;
 379                bitcnt = sum << 3;      /* need the size in bits */
 380
 381                tmp = bitcnt >> 16;
 382                dprintk(3,
 383                        "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
 384                        ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
 385                zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
 386                zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
 387                tmp = bitcnt & 0xffff;
 388                zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
 389                zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
 390
 391                bitcnt -= bitcnt >> 7;  // bits without stuffing
 392                bitcnt -= ((bitcnt * 5) >> 6);  // bits without eob
 393
 394                tmp = bitcnt >> 16;
 395                dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
 396                        ptr->name, bitcnt, tmp);
 397                zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
 398                zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
 399                tmp = bitcnt & 0xffff;
 400                zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
 401                zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
 402
 403                /* JPEG markers to be included in the compressed stream */
 404                zr36060_write(ptr, ZR060_MER,
 405                              ZR060_MER_DQT | ZR060_MER_DHT |
 406                              ((ptr->com.len > 0) ? ZR060_MER_COM : 0) |
 407                              ((ptr->app.len > 0) ? ZR060_MER_APP : 0));
 408
 409                /* Setup the Video Frontend */
 410                /* Limit pixel range to 16..235 as per CCIR-601 */
 411                zr36060_write(ptr, ZR060_VCR, ZR060_VCR_RANGE);
 412
 413        } else {
 414                dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
 415
 416                zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
 417
 418                /* 060 communicates with 067 in master mode */
 419                zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CODE_MSTR);
 420
 421                /* Decompression */
 422                zr36060_write(ptr, ZR060_CMR, 0);
 423
 424                /* Must be zero */
 425                zr36060_write(ptr, ZR060_MBZ, 0x00);
 426                zr36060_write(ptr, ZR060_TCR_HI, 0x00);
 427                zr36060_write(ptr, ZR060_TCR_LO, 0x00);
 428
 429                /* Disable all IRQs - no DataErr means autoreset */
 430                zr36060_write(ptr, ZR060_IMR, 0);
 431
 432                /* setup misc. data for expansion */
 433                zr36060_write(ptr, ZR060_MER, 0);
 434
 435/* setup the fixed jpeg tables - maybe variable, though - (see table init section above) */
 436                zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), zr36060_dht);
 437
 438                /* Setup the Video Frontend */
 439                //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FI_EXT);
 440                //this doesn't seem right and doesn't work...
 441                zr36060_write(ptr, ZR060_VCR, ZR060_VCR_RANGE);
 442        }
 443
 444        /* Load the tables */
 445        zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST | ZR060_LOAD_LOAD);
 446        zr36060_wait_end(ptr);
 447        dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name, ptr->status);
 448
 449        if (ptr->status & ZR060_CFSR_BUSY) {
 450                pr_err("%s: init aborted!\n", ptr->name);
 451                return;         // something is wrong, its timed out!!!!
 452        }
 453}
 454
 455/* =========================================================================
 456 * CODEC API FUNCTIONS
 457 * this functions are accessed by the master via the API structure
 458 * =========================================================================
 459 */
 460
 461/* set compressiion/expansion mode and launches codec -
 462 * this should be the last call from the master before starting processing
 463 */
 464static int zr36060_set_mode(struct videocodec *codec, int mode)
 465{
 466        struct zr36060 *ptr = (struct zr36060 *)codec->data;
 467
 468        dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
 469
 470        if (mode != CODEC_DO_EXPANSION && mode != CODEC_DO_COMPRESSION)
 471                return -EINVAL;
 472
 473        ptr->mode = mode;
 474        zr36060_init(ptr);
 475
 476        return 0;
 477}
 478
 479/* set picture size (norm is ignored as the codec doesn't know about it) */
 480static int zr36060_set_video(struct videocodec *codec, const struct tvnorm *norm,
 481                             struct vfe_settings *cap, struct vfe_polarity *pol)
 482{
 483        struct zr36060 *ptr = (struct zr36060 *)codec->data;
 484        u32 reg;
 485        int size;
 486
 487        dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
 488                cap->x, cap->y, cap->width, cap->height, cap->decimation);
 489
 490        /* if () return -EINVAL;
 491         * trust the master driver that it knows what it does - so
 492         * we allow invalid startx/y and norm for now ...
 493         */
 494        ptr->width = cap->width / (cap->decimation & 0xff);
 495        ptr->height = cap->height / (cap->decimation >> 8);
 496
 497        zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
 498
 499        /* Note that VSPol/HSPol bits in zr36060 have the opposite
 500         * meaning of their zr360x7 counterparts with the same names
 501         * N.b. for VSPol this is only true if FIVEdge = 0 (default,
 502         * left unchanged here - in accordance with datasheet).
 503         */
 504        reg = (!pol->vsync_pol ? ZR060_VPR_VS_POL : 0)
 505            | (!pol->hsync_pol ? ZR060_VPR_HS_POL : 0)
 506            | (pol->field_pol ? ZR060_VPR_FI_POL : 0)
 507            | (pol->blank_pol ? ZR060_VPR_BL_POL : 0)
 508            | (pol->subimg_pol ? ZR060_VPR_S_IMG_POL : 0)
 509            | (pol->poe_pol ? ZR060_VPR_POE_POL : 0)
 510            | (pol->pvalid_pol ? ZR060_VPR_P_VAL_POL : 0)
 511            | (pol->vclk_pol ? ZR060_VPR_VCLK_POL : 0);
 512        zr36060_write(ptr, ZR060_VPR, reg);
 513
 514        reg = 0;
 515        switch (cap->decimation & 0xff) {
 516        default:
 517        case 1:
 518                break;
 519
 520        case 2:
 521                reg |= ZR060_SR_H_SCALE2;
 522                break;
 523
 524        case 4:
 525                reg |= ZR060_SR_H_SCALE4;
 526                break;
 527        }
 528
 529        switch (cap->decimation >> 8) {
 530        default:
 531        case 1:
 532                break;
 533
 534        case 2:
 535                reg |= ZR060_SR_V_SCALE;
 536                break;
 537        }
 538        zr36060_write(ptr, ZR060_SR, reg);
 539
 540        zr36060_write(ptr, ZR060_BCR_Y, 0x00);
 541        zr36060_write(ptr, ZR060_BCR_U, 0x80);
 542        zr36060_write(ptr, ZR060_BCR_V, 0x80);
 543
 544        /* sync generator */
 545
 546        reg = norm->ht - 1;     /* Vtotal */
 547        zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
 548        zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
 549
 550        reg = norm->wt - 1;     /* Htotal */
 551        zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
 552        zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
 553
 554        reg = 6 - 1;            /* VsyncSize */
 555        zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
 556
 557        //reg   = 30 - 1;               /* HsyncSize */
 558///*CP*/        reg = (zr->params.norm == 1 ? 57 : 68);
 559        reg = 68;
 560        zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
 561
 562        reg = norm->v_start - 1;        /* BVstart */
 563        zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
 564
 565        reg += norm->ha / 2;    /* BVend */
 566        zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
 567        zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
 568
 569        reg = norm->h_start - 1;        /* BHstart */
 570        zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
 571
 572        reg += norm->wa;        /* BHend */
 573        zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
 574        zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
 575
 576        /* active area */
 577        reg = cap->y + norm->v_start;   /* Vstart */
 578        zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
 579        zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
 580
 581        reg += cap->height;     /* Vend */
 582        zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
 583        zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
 584
 585        reg = cap->x + norm->h_start;   /* Hstart */
 586        zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
 587        zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
 588
 589        reg += cap->width;      /* Hend */
 590        zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
 591        zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
 592
 593        /* subimage area */
 594        reg = norm->v_start - 4;        /* SVstart */
 595        zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
 596        zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
 597
 598        reg += norm->ha / 2 + 8;        /* SVend */
 599        zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
 600        zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
 601
 602        reg = norm->h_start /*+ 64 */  - 4;     /* SHstart */
 603        zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
 604        zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
 605
 606        reg += norm->wa + 8;    /* SHend */
 607        zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
 608        zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
 609
 610        size = ptr->width * ptr->height;
 611        /* Target compressed field size in bits: */
 612        size = size * 16;       /* uncompressed size in bits */
 613        /* (Ronald) by default, quality = 100 is a compression
 614         * ratio 1:2. Setting low_bitrate (insmod option) sets
 615         * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
 616         * buz can't handle more at decimation=1... Use low_bitrate if
 617         * you have a Buz, unless you know what you're doing
 618         */
 619        size = size * cap->quality / (low_bitrate ? 400 : 200);
 620        /* Lower limit (arbitrary, 1 KB) */
 621        if (size < 8192)
 622                size = 8192;
 623        /* Upper limit: 7/8 of the code buffers */
 624        if (size > ptr->total_code_vol * 7)
 625                size = ptr->total_code_vol * 7;
 626
 627        ptr->real_code_vol = size >> 3; /* in bytes */
 628
 629        /* the MBCVR is the *maximum* block volume, according to the
 630         * JPEG ISO specs, this shouldn't be used, since that allows
 631         * for the best encoding quality. So set it to it's max value
 632         */
 633        reg = ptr->max_block_vol;
 634        zr36060_write(ptr, ZR060_MBCVR, reg);
 635
 636        return 0;
 637}
 638
 639/* additional control functions */
 640static int zr36060_control(struct videocodec *codec, int type, int size, void *data)
 641{
 642        struct zr36060 *ptr = (struct zr36060 *)codec->data;
 643        int *ival = (int *)data;
 644
 645        dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
 646                size);
 647
 648        switch (type) {
 649        case CODEC_G_STATUS:    /* get last status */
 650                if (size != sizeof(int))
 651                        return -EFAULT;
 652                zr36060_read_status(ptr);
 653                *ival = ptr->status;
 654                break;
 655
 656        case CODEC_G_CODEC_MODE:
 657                if (size != sizeof(int))
 658                        return -EFAULT;
 659                *ival = CODEC_MODE_BJPG;
 660                break;
 661
 662        case CODEC_S_CODEC_MODE:
 663                if (size != sizeof(int))
 664                        return -EFAULT;
 665                if (*ival != CODEC_MODE_BJPG)
 666                        return -EINVAL;
 667                /* not needed, do nothing */
 668                return 0;
 669
 670        case CODEC_G_VFE:
 671        case CODEC_S_VFE:
 672                /* not needed, do nothing */
 673                return 0;
 674
 675        case CODEC_S_MMAP:
 676                /* not available, give an error */
 677                return -ENXIO;
 678
 679        case CODEC_G_JPEG_TDS_BYTE:     /* get target volume in byte */
 680                if (size != sizeof(int))
 681                        return -EFAULT;
 682                *ival = ptr->total_code_vol;
 683                break;
 684
 685        case CODEC_S_JPEG_TDS_BYTE:     /* get target volume in byte */
 686                if (size != sizeof(int))
 687                        return -EFAULT;
 688                ptr->total_code_vol = *ival;
 689                ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
 690                break;
 691
 692        case CODEC_G_JPEG_SCALE:        /* get scaling factor */
 693                if (size != sizeof(int))
 694                        return -EFAULT;
 695                *ival = zr36060_read_scalefactor(ptr);
 696                break;
 697
 698        case CODEC_S_JPEG_SCALE:        /* set scaling factor */
 699                if (size != sizeof(int))
 700                        return -EFAULT;
 701                ptr->scalefact = *ival;
 702                break;
 703
 704        case CODEC_G_JPEG_APP_DATA: {   /* get appn marker data */
 705                struct jpeg_app_marker *app = data;
 706
 707                if (size != sizeof(struct jpeg_app_marker))
 708                        return -EFAULT;
 709
 710                *app = ptr->app;
 711                break;
 712        }
 713
 714        case CODEC_S_JPEG_APP_DATA: {   /* set appn marker data */
 715                struct jpeg_app_marker *app = data;
 716
 717                if (size != sizeof(struct jpeg_app_marker))
 718                        return -EFAULT;
 719
 720                ptr->app = *app;
 721                break;
 722        }
 723
 724        case CODEC_G_JPEG_COM_DATA: {   /* get comment marker data */
 725                struct jpeg_com_marker *com = data;
 726
 727                if (size != sizeof(struct jpeg_com_marker))
 728                        return -EFAULT;
 729
 730                *com = ptr->com;
 731                break;
 732        }
 733
 734        case CODEC_S_JPEG_COM_DATA: {   /* set comment marker data */
 735                struct jpeg_com_marker *com = data;
 736
 737                if (size != sizeof(struct jpeg_com_marker))
 738                        return -EFAULT;
 739
 740                ptr->com = *com;
 741                break;
 742        }
 743
 744        default:
 745                return -EINVAL;
 746        }
 747
 748        return size;
 749}
 750
 751/* =========================================================================
 752 * Exit and unregister function:
 753 * Deinitializes Zoran's JPEG processor
 754 * =========================================================================
 755 */
 756static int zr36060_unset(struct videocodec *codec)
 757{
 758        struct zr36060 *ptr = codec->data;
 759
 760        if (ptr) {
 761                /* do wee need some codec deinit here, too ???? */
 762
 763                dprintk(1, "%s: finished codec #%d\n", ptr->name, ptr->num);
 764                kfree(ptr);
 765                codec->data = NULL;
 766
 767                zr36060_codecs--;
 768                return 0;
 769        }
 770
 771        return -EFAULT;
 772}
 773
 774/* =========================================================================
 775 * Setup and registry function:
 776 * Initializes Zoran's JPEG processor
 777 * Also sets pixel size, average code size, mode (compr./decompr.)
 778 * (the given size is determined by the processor with the video interface)
 779 * =========================================================================
 780 */
 781static int zr36060_setup(struct videocodec *codec)
 782{
 783        struct zr36060 *ptr;
 784        int res;
 785
 786        dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n", zr36060_codecs);
 787
 788        if (zr36060_codecs == MAX_CODECS) {
 789                pr_err("zr36060: Can't attach more codecs!\n");
 790                return -ENOSPC;
 791        }
 792        //mem structure init
 793        ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
 794        codec->data = ptr;
 795        if (!ptr)
 796                return -ENOMEM;
 797
 798        snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]", zr36060_codecs);
 799        ptr->num = zr36060_codecs++;
 800        ptr->codec = codec;
 801
 802        //testing
 803        res = zr36060_basic_test(ptr);
 804        if (res < 0) {
 805                zr36060_unset(codec);
 806                return res;
 807        }
 808        //final setup
 809        memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
 810        memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
 811
 812        ptr->bitrate_ctrl = 0;  /* 0 or 1 - fixed file size flag (what is the difference?) */
 813        ptr->mode = CODEC_DO_COMPRESSION;
 814        ptr->width = 384;
 815        ptr->height = 288;
 816        ptr->total_code_vol = 16000;    /* CHECKME */
 817        ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
 818        ptr->max_block_vol = 240;       /* CHECKME, was 120 is 240 */
 819        ptr->scalefact = 0x100;
 820        ptr->dri = 1;           /* CHECKME, was 8 is 1 */
 821
 822        /* by default, no COM or APP markers - app should set those */
 823        ptr->com.len = 0;
 824        ptr->app.appn = 0;
 825        ptr->app.len = 0;
 826
 827        zr36060_init(ptr);
 828
 829        dprintk(1, KERN_INFO "%s: codec attached and running\n", ptr->name);
 830
 831        return 0;
 832}
 833
 834static const struct videocodec zr36060_codec = {
 835        .owner = THIS_MODULE,
 836        .name = "zr36060",
 837        .magic = 0L,            // magic not used
 838        .flags =
 839            CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
 840            CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
 841        .type = CODEC_TYPE_ZR36060,
 842        .setup = zr36060_setup, // functionality
 843        .unset = zr36060_unset,
 844        .set_mode = zr36060_set_mode,
 845        .set_video = zr36060_set_video,
 846        .control = zr36060_control,
 847        // others are not used
 848};
 849
 850static int __init zr36060_init_module(void)
 851{
 852        zr36060_codecs = 0;
 853        return videocodec_register(&zr36060_codec);
 854}
 855
 856static void __exit zr36060_cleanup_module(void)
 857{
 858        if (zr36060_codecs) {
 859                dprintk(1,
 860                        "zr36060: something's wrong - %d codecs left somehow.\n",
 861                        zr36060_codecs);
 862        }
 863
 864        /* however, we can't just stay alive */
 865        videocodec_unregister(&zr36060_codec);
 866}
 867
 868module_init(zr36060_init_module);
 869module_exit(zr36060_cleanup_module);
 870
 871MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");
 872MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors " ZR060_VERSION);
 873MODULE_LICENSE("GPL");
 874